Compare commits
166
Commits
showroom-RC.1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49a0944412 | ||
|
|
d6e525465b | ||
|
|
91e0ff102e | ||
|
|
be549a75f6 | ||
|
|
1e27fcca51 | ||
|
|
ab5d43a397 | ||
|
|
094d6ec86f | ||
|
|
6475b0c126 | ||
|
|
a7f0bb7650 | ||
|
|
50d08c7efd | ||
|
|
4e780cb6d4 | ||
|
|
26fadc74e4 | ||
|
|
9f043d25e9 | ||
|
|
72e8abe604 | ||
|
|
637ff76ca8 | ||
|
|
ad25acf851 | ||
|
|
0f3912f6fd | ||
|
|
2553869978 | ||
|
|
d1290e31bc | ||
|
|
598f09bba5 | ||
|
|
fb11eac920 | ||
|
|
0973d0afe5 | ||
|
|
785eea77db | ||
|
|
2e69e3fd4c | ||
|
|
dc39ddbbea | ||
|
|
c97e0f8ba1 | ||
|
|
9adc940a67 | ||
|
|
58cd990c8c | ||
|
|
e08a2639c6 | ||
|
|
2ffad14939 | ||
|
|
33210e10f2 | ||
|
|
472762edfa | ||
|
|
89287879bc | ||
|
|
3411804c42 | ||
|
|
de0f246fb3 | ||
|
|
a180696fc7 | ||
|
|
ccd47590d5 | ||
|
|
5dd6874488 | ||
|
|
514f3bd89e | ||
|
|
0aea7a0db1 | ||
|
|
b2fe2731c2 | ||
|
|
f6e72bbe19 | ||
|
|
6fb9e4806d | ||
|
|
b764ef206e | ||
|
|
0615369680 | ||
|
|
954fc9ead1 | ||
|
|
79db3e3896 | ||
|
|
5510ac0abf | ||
|
|
2d23821da4 | ||
|
|
fca4395934 | ||
|
|
31cfa90501 | ||
|
|
ccab226e12 | ||
|
|
1b53514906 | ||
|
|
25b41d2a43 | ||
|
|
eb20184257 | ||
|
|
c285c6ccb8 | ||
|
|
fa07acdd31 | ||
|
|
9ad0aa199f | ||
|
|
7ab8742528 | ||
|
|
8ec6b54b6c | ||
|
|
f21817dec1 | ||
|
|
4cb8f6aee1 | ||
|
|
b3e863e943 | ||
|
|
4aed87ebd0 | ||
|
|
fafd439b26 | ||
|
|
226561ffd4 | ||
|
|
85772b4ca7 | ||
|
|
57376251fa | ||
|
|
8a05ca54b2 | ||
|
|
9344a61b61 | ||
|
|
18f4aba146 | ||
|
|
1eb61fe020 | ||
|
|
a11650f2b4 | ||
|
|
f09e9563b2 | ||
|
|
c914e7e348 | ||
|
|
b5f3769416 | ||
|
|
3133fd480b | ||
|
|
b20732f9a8 | ||
|
|
8b486ffc60 | ||
|
|
7d5bedcb0c | ||
|
|
268c8b619b | ||
|
|
bbeb5f01ac | ||
|
|
bd1a1de792 | ||
|
|
af9630060a | ||
|
|
383ca8b173 | ||
|
|
afc654c704 | ||
|
|
106129c27c | ||
|
|
81810c5af4 | ||
|
|
12c076c349 | ||
|
|
9d45086951 | ||
|
|
8777adbe2e | ||
|
|
82a22114d3 | ||
|
|
098f083b8d | ||
|
|
e8586eb4da | ||
|
|
1e1a762b9b | ||
|
|
e9146c29ce | ||
|
|
042e111bc4 | ||
|
|
2f56697bb7 | ||
|
|
55700094a2 | ||
|
|
9bfbd861ca | ||
|
|
5f26b3e160 | ||
|
|
1b9f8e3ab4 | ||
|
|
c90cfa63e4 | ||
|
|
7bc3c13ad6 | ||
|
|
1ee4e95491 | ||
|
|
bf5f1a63ff | ||
|
|
38648c1670 | ||
|
|
1d4fcf0d89 | ||
|
|
73417de740 | ||
|
|
0edc6fd23a | ||
|
|
abb106d7c2 | ||
|
|
be2da7afe0 | ||
|
|
243f5b689c | ||
|
|
301d403887 | ||
|
|
08e5ed7202 | ||
|
|
4ca87255ab | ||
|
|
4b2ab455c9 | ||
|
|
b9c809d2c7 | ||
|
|
ed483507e5 | ||
|
|
8feebe3d1e | ||
|
|
5c7f02554f | ||
|
|
58161d2b57 | ||
|
|
ce192b080e | ||
|
|
aafe1c5460 | ||
|
|
8539255353 | ||
|
|
5706aea93b | ||
|
|
9369b73118 | ||
|
|
ab9f1d3cc4 | ||
|
|
8d0f110c50 | ||
|
|
cedbce376b | ||
|
|
6e2a36fe0c | ||
|
|
d9f3677b98 | ||
|
|
5b82dfb691 | ||
|
|
728f8e6d31 | ||
|
|
9acef9d37e | ||
|
|
542ac42fca | ||
|
|
dbd7b88639 | ||
|
|
28c7a0965a | ||
|
|
b5d76ec5e6 | ||
|
|
83cbcefff9 | ||
|
|
0d940c99db | ||
|
|
2334eb741b | ||
|
|
ddc28956c4 | ||
|
|
abbcb19838 | ||
|
|
024afdfd3d | ||
|
|
b9f2b16d24 | ||
|
|
3f9ba49255 | ||
|
|
f01fdbdd9c | ||
|
|
7563311a19 | ||
|
|
669341f1d6 | ||
|
|
13aafca7e4 | ||
|
|
e24eec56e7 | ||
|
|
eba58a57bf | ||
|
|
e190f5f47d | ||
|
|
ec6f23e149 | ||
|
|
fdd842fe19 | ||
|
|
73ec6d3c1e | ||
|
|
dee5085c89 | ||
|
|
c4ab89f177 | ||
|
|
d1b069ad8b | ||
|
|
c56a523286 | ||
|
|
8b5d721bfd | ||
|
|
7ed9dc54bf | ||
|
|
adee2f54e3 | ||
|
|
41e3e6dfb2 | ||
|
|
5f6a9ac5d1 |
@@ -24,3 +24,8 @@ typescript
|
|||||||
.directory
|
.directory
|
||||||
|
|
||||||
*.old_patched
|
*.old_patched
|
||||||
|
|
||||||
|
sync_uploads
|
||||||
|
|
||||||
|
vendor
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+158
@@ -1,3 +1,161 @@
|
|||||||
|
Drupal 7.73, 2020-09-16
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues:
|
||||||
|
- SA-CORE-2020-007
|
||||||
|
|
||||||
|
Drupal 7.72, 2020-06-17
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues:
|
||||||
|
- SA-CORE-2020-004
|
||||||
|
|
||||||
|
Drupal 7.71, 2020-06-03
|
||||||
|
-----------------------
|
||||||
|
- Fix for jQuery Form bug in Chromium-based browsers
|
||||||
|
- Full support for PHP 7.4
|
||||||
|
|
||||||
|
Drupal 7.70, 2020-05-19
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues:
|
||||||
|
- SA-CORE-2020-002
|
||||||
|
- SA-CORE-2020-003
|
||||||
|
|
||||||
|
Drupal 7.69, 2019-12-18
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues:
|
||||||
|
- SA-CORE-2019-012
|
||||||
|
|
||||||
|
Drupal 7.68, 2019-12-04
|
||||||
|
-----------------------
|
||||||
|
- Fixed: Hide toolbar when printing
|
||||||
|
- Fixed: Settings returned via ajax are not run through hook_js_alter()
|
||||||
|
- Fixed: Use drupal_http_build_query() in drupal_http_request()
|
||||||
|
- Fixed: DrupalRequestSanitizer not found fatal error when bootstrap phase order is changed
|
||||||
|
- Fixed: Block web.config in .htaccess (and vice-versa)
|
||||||
|
- Fixed: Create "scripts" element to align rendering workflow to how "styles" are handled
|
||||||
|
- PHP 7.3: Fixed 'Cannot change session id when session is active'
|
||||||
|
- PHP 7.1: Fixed 'A non-numeric value encountered in theme_pager()'
|
||||||
|
- PHP 7.x: Fixed file.inc generated .htaccess does not cover PHP 7
|
||||||
|
- PHP 5.3: Fixed check_plain() 'Invalid multibyte sequence in argument' test failures
|
||||||
|
- Fixed: Allow passing data as array to drupal_http_request()
|
||||||
|
- Fixed: Skip module_invoke/module_hook in calling hook_watchdog (excessive function_exist)
|
||||||
|
- Fixed: HTTP status 200 returned for 'Additional uncaught exception thrown while handling exception'
|
||||||
|
- Fixed: theme_table() should take an optional footer variable and produce <tfoot>
|
||||||
|
- Fixed: 'uasort() expects parameter 1 to be array, null given in node_view_multiple()'
|
||||||
|
- [regression] Fix default.settings.php permission
|
||||||
|
|
||||||
|
Drupal 7.67, 2019-05-08
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues:
|
||||||
|
- SA-CORE-2019-007
|
||||||
|
|
||||||
|
Drupal 7.66, 2019-04-17
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues:
|
||||||
|
- SA-CORE-2019-006
|
||||||
|
|
||||||
|
Drupal 7.65, 2019-03-20
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues:
|
||||||
|
- SA-CORE-2019-004
|
||||||
|
|
||||||
|
Drupal 7.64, 2019-02-06
|
||||||
|
-----------------------
|
||||||
|
- [regression] Unset the 'host' header in drupal_http_request() during redirect
|
||||||
|
- Fixed: 7.x does not have Phar protection and Phar tests are failing on Drupal 7
|
||||||
|
- Fixed: Notice: Undefined index: display_field in file_field_widget_value() (line 582 of /module/file/file.field.inc)
|
||||||
|
- Performance improvement: Registry rebuild should not parse the same file twice in the same request
|
||||||
|
- Fixed _registry_update() to clear caches after transaction is committed
|
||||||
|
|
||||||
|
Drupal 7.63, 2019-01-16
|
||||||
|
-----------------------
|
||||||
|
- Fixed a fatal error for some Drush users introduced by SA-CORE-2019-002.
|
||||||
|
|
||||||
|
Drupal 7.62, 2019-01-15
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues:
|
||||||
|
- SA-CORE-2019-001
|
||||||
|
- SA-CORE-2019-002
|
||||||
|
|
||||||
|
Drupal 7.61, 2018-11-07
|
||||||
|
-----------------------
|
||||||
|
- File upload validation functions and hook_file_validate() implementations are
|
||||||
|
now always passed the correct file URI.
|
||||||
|
- The default form cache expiration of 6 hours is now configurable (API
|
||||||
|
addition: https://www.drupal.org/node/2857751).
|
||||||
|
- Allowed callers of drupal_http_request() to optionally specify an explicit
|
||||||
|
Host header.
|
||||||
|
- Allowed the + character to appear in usernames.
|
||||||
|
- PHP 7.2: Fixed Archive_Tar incompatibility.
|
||||||
|
- PHP 7.2: Removed deprecated function each().
|
||||||
|
- PHP 7.2: Avoid count() calls on uncountable variables.
|
||||||
|
- PHP 7.2: Removed deprecated create_function() call.
|
||||||
|
- PHP 7.2: Make sure variables are arrays in theme_links().
|
||||||
|
- Fixed theme-settings.php not being loaded on cached forms
|
||||||
|
- Fixed problem with IE11 & Chrome(PointerEvents enabled) & some Firefox scroll to the top of the page after dragging the bottom item with jquery 1.5 <-> 1.11
|
||||||
|
|
||||||
|
Drupal 7.60, 2018-10-18
|
||||||
|
------------------------
|
||||||
|
- Fixed security issues. See SA-CORE-2018-006.
|
||||||
|
|
||||||
|
Drupal 7.59, 2018-04-25
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues (remote code execution). See SA-CORE-2018-004.
|
||||||
|
|
||||||
|
Drupal 7.58, 2018-03-28
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues (remote code execution). See SA-CORE-2018-002.
|
||||||
|
|
||||||
|
Drupal 7.57, 2018-02-21
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2018-001.
|
||||||
|
|
||||||
|
Drupal 7.56, 2017-06-21
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues (access bypass). See SA-CORE-2017-003.
|
||||||
|
|
||||||
|
Drupal 7.55, 2017-06-07
|
||||||
|
-----------------------
|
||||||
|
- Fixed incompatibility with PHP versions 7.0.19 and 7.1.5 due to duplicate
|
||||||
|
DATE_RFC7231 definition.
|
||||||
|
- Made Drupal core pass all automated tests on PHP 7.1.
|
||||||
|
- Allowed services such as Let's Encrypt to work with Drupal on Apache, by
|
||||||
|
making Drupal's .htaccess file allow access to the .well-known directory
|
||||||
|
defined by RFC 5785.
|
||||||
|
- Made new Drupal sites work correctly on Apache 2.4 when the mod_access_compat
|
||||||
|
Apache module is disabled.
|
||||||
|
- Fixed Drupal's URL-generating functions to always encode '[' and ']' so that
|
||||||
|
the URLs will pass HTML5 validation.
|
||||||
|
- Various additional bug fixes.
|
||||||
|
- Various API documentation improvements.
|
||||||
|
- Additional automated test coverage.
|
||||||
|
|
||||||
|
Drupal 7.54, 2017-02-01
|
||||||
|
-----------------------
|
||||||
|
- Modules are now able to define theme engines (API addition:
|
||||||
|
https://www.drupal.org/node/2826480).
|
||||||
|
- Logging of searches can now be disabled (new option in the administrative
|
||||||
|
interface).
|
||||||
|
- Added menu tree render structure to (pre-)process hooks for theme_menu_tree()
|
||||||
|
(API addition: https://www.drupal.org/node/2827134).
|
||||||
|
- Added new function for determining whether an HTTPS request is being served
|
||||||
|
(API addition: https://www.drupal.org/node/2824590).
|
||||||
|
- Fixed incorrect default value for short and medium date formats on the date
|
||||||
|
type configuration page.
|
||||||
|
- File validation error message is now removed after subsequent upload of valid
|
||||||
|
file.
|
||||||
|
- Numerous bug fixes.
|
||||||
|
- Numerous API documentation improvements.
|
||||||
|
- Additional performance improvements.
|
||||||
|
- Additional automated test coverage.
|
||||||
|
|
||||||
|
Drupal 7.53, 2016-12-07
|
||||||
|
-----------------------
|
||||||
|
- Fixed drag and drop support on newer Chrome/IE 11+ versions after 7.51 update
|
||||||
|
when jQuery is updated to 1.7-1.11.0.
|
||||||
|
|
||||||
|
Drupal 7.52, 2016-11-16
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2016-005.
|
||||||
|
|
||||||
Drupal 7.51, 2016-10-05
|
Drupal 7.51, 2016-10-05
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|||||||
Executable → Regular
@@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
CREATE THE MySQL DATABASE
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
This step is only necessary if you don't already have a database set up (e.g.,
|
||||||
|
by your host). In the following examples, 'username' is an example MySQL user
|
||||||
|
which has the CREATE and GRANT privileges. Use the appropriate user name for
|
||||||
|
your system.
|
||||||
|
|
||||||
|
First, you must create a new database for your Drupal site (here, 'databasename'
|
||||||
|
is the name of the new database):
|
||||||
|
|
||||||
|
mysqladmin -u username -p create databasename
|
||||||
|
|
||||||
|
MySQL will prompt for the 'username' database password and then create the
|
||||||
|
initial database files. Next you must log in and set the access database rights:
|
||||||
|
|
||||||
|
mysql -u username -p
|
||||||
|
|
||||||
|
Again, you will be asked for the 'username' database password. At the MySQL
|
||||||
|
prompt, enter the following command:
|
||||||
|
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER,
|
||||||
|
CREATE TEMPORARY TABLES ON databasename.*
|
||||||
|
TO 'username'@'localhost' IDENTIFIED BY 'password';
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
'databasename' is the name of your database
|
||||||
|
'username' is the username of your MySQL account
|
||||||
|
'localhost' is the web server host where Drupal is installed
|
||||||
|
'password' is the password required for that username
|
||||||
|
|
||||||
|
Note: Unless the database user/host combination for your Drupal installation
|
||||||
|
has all of the privileges listed above (except possibly CREATE TEMPORARY TABLES,
|
||||||
|
which is currently only used by Drupal core automated tests and some
|
||||||
|
contributed modules), you will not be able to install or run Drupal.
|
||||||
|
|
||||||
|
If successful, MySQL will reply with:
|
||||||
|
|
||||||
|
Query OK, 0 rows affected
|
||||||
|
|
||||||
|
If the InnoDB storage engine is available, it will be used for all database
|
||||||
|
tables. InnoDB provides features over MyISAM such as transaction support,
|
||||||
|
row-level locks, and consistent non-locking reads.
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
CREATE THE PostgreSQL DATABASE
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Note that the database must be created with UTF-8 (Unicode) encoding.
|
||||||
|
|
||||||
|
1. CREATE DATABASE USER
|
||||||
|
|
||||||
|
This step is only necessary if you don't already have a user set up (e.g., by
|
||||||
|
your host), or want to create a new user for use with Drupal only. The
|
||||||
|
following command creates a new user named 'username' and asks for a password
|
||||||
|
for that user:
|
||||||
|
|
||||||
|
createuser --pwprompt --encrypted --no-createrole --no-createdb username
|
||||||
|
|
||||||
|
If there are no errors, then the command was successful.
|
||||||
|
|
||||||
|
2. CREATE DRUPAL DATABASE
|
||||||
|
|
||||||
|
This step is only necessary if you don't already have a database set up
|
||||||
|
(e.g., by your host) or want to create a new database for use with Drupal
|
||||||
|
only. The following command creates a new database named 'databasename',
|
||||||
|
which is owned by the previously created 'username':
|
||||||
|
|
||||||
|
createdb --encoding=UTF8 --owner=username databasename
|
||||||
|
|
||||||
|
If there are no errors, then the command was successful.
|
||||||
|
|
||||||
|
3. CREATE SCHEMA OR SCHEMAS (Optional advanced step)
|
||||||
|
|
||||||
|
Drupal will run across different schemas within your database if you so wish.
|
||||||
|
By default, Drupal runs inside the 'public' schema but you can use $db_prefix
|
||||||
|
inside settings.php to define a schema for Drupal to run inside of, or
|
||||||
|
specify tables that are shared inside of a separate schema. Drupal will not
|
||||||
|
create schemas for you. In fact, the user that Drupal runs as should not be
|
||||||
|
allowed to do this. You'll need to execute the SQL below as a superuser,
|
||||||
|
replace 'username' with the username that Drupal uses to connect to
|
||||||
|
PostgreSQL, and replace 'schema_name' with a schema name you wish to use,
|
||||||
|
such as 'shared':
|
||||||
|
|
||||||
|
CREATE SCHEMA schema_name AUTHORIZATION username;
|
||||||
|
|
||||||
|
Do this for as many schemas as you need. See default.settings.php for
|
||||||
|
instructions on how to set which tables use which schemas.
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
SQLITE REQUIREMENTS
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
To use SQLite with your Drupal installation, the following requirements must be
|
||||||
|
met: Server has PHP 5.2 or later with PDO, and the PDO SQLite driver must be
|
||||||
|
enabled.
|
||||||
|
|
||||||
|
SQLITE DATABASE CREATION
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The Drupal installer will create the SQLite database for you. The only
|
||||||
|
requirement is that the installer must have write permissions to the directory
|
||||||
|
where the database file resides. This directory (not just the database file) also
|
||||||
|
has to remain writeable by the web server going forward for SQLite to continue to
|
||||||
|
be able to operate.
|
||||||
|
|
||||||
|
On the "Database configuration" form in the "Database file" field, you must
|
||||||
|
supply the exact path to where you wish your database file to reside. It is
|
||||||
|
strongly suggested that you choose a path that is outside of the webroot, yet
|
||||||
|
ensure that the directory is writeable by the web server.
|
||||||
|
|
||||||
|
If you must place your database file in your webroot, you could try using the
|
||||||
|
following in your "Database file" field:
|
||||||
|
|
||||||
|
sites/default/files/.ht.sqlite
|
||||||
|
|
||||||
|
Note: The .ht in the name will tell Apache to prevent the database from being
|
||||||
|
downloaded. Please check that the file is, indeed, protected by your webserver.
|
||||||
|
If not, please consult the documentation of your webserver on how to protect a
|
||||||
|
file from downloading.
|
||||||
+400
@@ -0,0 +1,400 @@
|
|||||||
|
|
||||||
|
CONTENTS OF THIS FILE
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
* Requirements and notes
|
||||||
|
* Optional server requirements
|
||||||
|
* Installation
|
||||||
|
* Building and customizing your site
|
||||||
|
* Multisite configuration
|
||||||
|
* More information
|
||||||
|
|
||||||
|
REQUIREMENTS AND NOTES
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Drupal requires:
|
||||||
|
|
||||||
|
- A web server. Apache (version 2.0 or greater) is recommended.
|
||||||
|
- PHP 5.2.4 (or greater) (http://www.php.net/).
|
||||||
|
- One of the following databases:
|
||||||
|
- MySQL 5.0.15 (or greater) (http://www.mysql.com/).
|
||||||
|
- MariaDB 5.1.44 (or greater) (http://mariadb.org/). MariaDB is a fully
|
||||||
|
compatible drop-in replacement for MySQL.
|
||||||
|
- Percona Server 5.1.70 (or greater) (http://www.percona.com/). Percona
|
||||||
|
Server is a backwards-compatible replacement for MySQL.
|
||||||
|
- PostgreSQL 8.3 (or greater) (http://www.postgresql.org/).
|
||||||
|
- SQLite 3.3.7 (or greater) (http://www.sqlite.org/).
|
||||||
|
|
||||||
|
For more detailed information about Drupal requirements, including a list of
|
||||||
|
PHP extensions and configurations that are required, see "System requirements"
|
||||||
|
(http://drupal.org/requirements) in the Drupal.org online documentation.
|
||||||
|
|
||||||
|
For detailed information on how to configure a test server environment using a
|
||||||
|
variety of operating systems and web servers, see "Local server setup"
|
||||||
|
(http://drupal.org/node/157602) in the Drupal.org online documentation.
|
||||||
|
|
||||||
|
Note that all directories mentioned in this document are always relative to the
|
||||||
|
directory of your Drupal installation, and commands are meant to be run from
|
||||||
|
this directory (except for the initial commands that create that directory).
|
||||||
|
|
||||||
|
OPTIONAL SERVER REQUIREMENTS
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
- If you want to use Drupal's "Clean URLs" feature on an Apache web server, you
|
||||||
|
will need the mod_rewrite module and the ability to use local .htaccess
|
||||||
|
files. For Clean URLs support on IIS, see "Clean URLs with IIS"
|
||||||
|
(http://drupal.org/node/3854) in the Drupal.org online documentation.
|
||||||
|
|
||||||
|
- If you plan to use XML-based services such as RSS aggregation, you will need
|
||||||
|
PHP's XML extension. This extension is enabled by default on most PHP
|
||||||
|
installations.
|
||||||
|
|
||||||
|
- To serve gzip compressed CSS and JS files on an Apache web server, you will
|
||||||
|
need the mod_headers module and the ability to use local .htaccess files.
|
||||||
|
|
||||||
|
- Some Drupal functionality (e.g., checking whether Drupal and contributed
|
||||||
|
modules need updates, RSS aggregation, etc.) require that the web server be
|
||||||
|
able to go out to the web and download information. If you want to use this
|
||||||
|
functionality, you need to verify that your hosting provider or server
|
||||||
|
configuration allows the web server to initiate outbound connections. Most web
|
||||||
|
hosting setups allow this.
|
||||||
|
|
||||||
|
INSTALLATION
|
||||||
|
------------
|
||||||
|
|
||||||
|
1. Download and extract Drupal.
|
||||||
|
|
||||||
|
You can obtain the latest Drupal release from http://drupal.org -- the files
|
||||||
|
are available in .tar.gz and .zip formats and can be extracted using most
|
||||||
|
compression tools.
|
||||||
|
|
||||||
|
To download and extract the files, on a typical Unix/Linux command line, use
|
||||||
|
the following commands (assuming you want version x.y of Drupal in .tar.gz
|
||||||
|
format):
|
||||||
|
|
||||||
|
wget http://drupal.org/files/projects/drupal-x.y.tar.gz
|
||||||
|
tar -zxvf drupal-x.y.tar.gz
|
||||||
|
|
||||||
|
This will create a new directory drupal-x.y/ containing all Drupal files and
|
||||||
|
directories. Then, to move the contents of that directory into a directory
|
||||||
|
within your web server's document root or your public HTML directory,
|
||||||
|
continue with this command:
|
||||||
|
|
||||||
|
mv drupal-x.y/* drupal-x.y/.htaccess /path/to/your/installation
|
||||||
|
|
||||||
|
2. Optionally, download a translation.
|
||||||
|
|
||||||
|
By default, Drupal is installed in English, and further languages may be
|
||||||
|
installed later. If you prefer to install Drupal in another language
|
||||||
|
initially:
|
||||||
|
|
||||||
|
- Download a translation file for the correct Drupal version and language
|
||||||
|
from the translation server: http://localize.drupal.org/translate/downloads
|
||||||
|
|
||||||
|
- Place the file into your installation profile's translations directory.
|
||||||
|
For instance, if you are using the Standard installation profile,
|
||||||
|
move the .po file into the directory:
|
||||||
|
|
||||||
|
profiles/standard/translations/
|
||||||
|
|
||||||
|
For detailed instructions, visit http://drupal.org/localize
|
||||||
|
|
||||||
|
3. Create the Drupal database.
|
||||||
|
|
||||||
|
Because Drupal stores all site information in a database, you must create
|
||||||
|
this database in order to install Drupal, and grant Drupal certain database
|
||||||
|
privileges (such as the ability to create tables). For details, consult
|
||||||
|
INSTALL.mysql.txt, INSTALL.pgsql.txt, or INSTALL.sqlite.txt. You may also
|
||||||
|
need to consult your web hosting provider for instructions specific to your
|
||||||
|
web host.
|
||||||
|
|
||||||
|
Take note of the username, password, database name, and hostname as you
|
||||||
|
create the database. You will enter this information during the install.
|
||||||
|
|
||||||
|
4. Run the install script.
|
||||||
|
|
||||||
|
To run the install script, point your browser to the base URL of your
|
||||||
|
website (e.g., http://www.example.com).
|
||||||
|
|
||||||
|
You will be guided through several screens to set up the database, add the
|
||||||
|
site maintenance account (the first user, also known as user/1), and provide
|
||||||
|
basic web site settings.
|
||||||
|
|
||||||
|
During installation, several files and directories need to be created, which
|
||||||
|
the install script will try to do automatically. However, on some hosting
|
||||||
|
environments, manual steps are required, and the install script will tell
|
||||||
|
you that it cannot proceed until you fix certain issues. This is normal and
|
||||||
|
does not indicate a problem with your server.
|
||||||
|
|
||||||
|
The most common steps you may need to perform are:
|
||||||
|
|
||||||
|
a. Missing files directory.
|
||||||
|
|
||||||
|
The install script will attempt to create a file storage directory in
|
||||||
|
the default location at sites/default/files (the location of the files
|
||||||
|
directory may be changed after Drupal is installed).
|
||||||
|
|
||||||
|
If auto-creation fails, you can make it work by changing permissions on
|
||||||
|
the sites/default directory so that the web server can create the files
|
||||||
|
directory within it for you. (If you are creating a multisite
|
||||||
|
installation, substitute the correct sites directory for sites/default;
|
||||||
|
see the Multisite Configuration section of this file, below.)
|
||||||
|
|
||||||
|
For example, on a Unix/Linux command line, you can grant everyone
|
||||||
|
(including the web server) permission to write to the sites/default
|
||||||
|
directory with this command:
|
||||||
|
|
||||||
|
chmod a+w sites/default
|
||||||
|
|
||||||
|
Be sure to set the permissions back after the installation is finished!
|
||||||
|
Sample command:
|
||||||
|
|
||||||
|
chmod go-w sites/default
|
||||||
|
|
||||||
|
Alternatively, instead of allowing the web server to create the files
|
||||||
|
directory for you as described above, you can create it yourself. Sample
|
||||||
|
commands from a Unix/Linux command line:
|
||||||
|
|
||||||
|
mkdir sites/default/files
|
||||||
|
chmod a+w sites/default/files
|
||||||
|
|
||||||
|
b. Missing settings file.
|
||||||
|
|
||||||
|
Drupal will try to automatically create a settings.php configuration file,
|
||||||
|
which is normally in the directory sites/default (to avoid problems when
|
||||||
|
upgrading, Drupal is not packaged with this file). If auto-creation fails,
|
||||||
|
you will need to create this file yourself, using the file
|
||||||
|
sites/default/default.settings.php as a template.
|
||||||
|
|
||||||
|
For example, on a Unix/Linux command line, you can make a copy of the
|
||||||
|
default.settings.php file with the command:
|
||||||
|
|
||||||
|
cp sites/default/default.settings.php sites/default/settings.php
|
||||||
|
|
||||||
|
Next, grant write privileges to the file to everyone (including the web
|
||||||
|
server) with the command:
|
||||||
|
|
||||||
|
chmod a+w sites/default/settings.php
|
||||||
|
|
||||||
|
Be sure to set the permissions back after the installation is finished!
|
||||||
|
Sample command:
|
||||||
|
|
||||||
|
chmod go-w sites/default/settings.php
|
||||||
|
|
||||||
|
c. Write permissions after install.
|
||||||
|
|
||||||
|
The install script will attempt to write-protect the settings.php file and
|
||||||
|
the sites/default directory after saving your configuration. If this
|
||||||
|
fails, you will be notified, and you can do it manually. Sample commands
|
||||||
|
from a Unix/Linux command line:
|
||||||
|
|
||||||
|
chmod go-w sites/default/settings.php
|
||||||
|
chmod go-w sites/default
|
||||||
|
|
||||||
|
5. Verify that the site is working.
|
||||||
|
|
||||||
|
When the install script finishes, you will be logged in with the site
|
||||||
|
maintenance account on a "Welcome" page. If the default Drupal theme is not
|
||||||
|
displaying properly and links on the page result in "Page Not Found" errors,
|
||||||
|
you may be experiencing problems with clean URLs. Visit
|
||||||
|
http://drupal.org/getting-started/clean-urls to troubleshoot.
|
||||||
|
|
||||||
|
6. Change file system storage settings (optional).
|
||||||
|
|
||||||
|
The files directory created in step 4 is the default file system path used to
|
||||||
|
store all uploaded files, as well as some temporary files created by
|
||||||
|
Drupal. After installation, you can modify the file system path to store
|
||||||
|
uploaded files in a different location.
|
||||||
|
|
||||||
|
It is not necessary to modify this path, but you may wish to change it if:
|
||||||
|
|
||||||
|
- Your site runs multiple Drupal installations from a single codebase (modify
|
||||||
|
the file system path of each installation to a different directory so that
|
||||||
|
uploads do not overlap between installations).
|
||||||
|
|
||||||
|
- Your site runs on a number of web servers behind a load balancer or reverse
|
||||||
|
proxy (modify the file system path on each server to point to a shared file
|
||||||
|
repository).
|
||||||
|
|
||||||
|
- You want to restrict access to uploaded files.
|
||||||
|
|
||||||
|
To modify the file system path:
|
||||||
|
|
||||||
|
a. Ensure that the new location for the path exists and is writable by the
|
||||||
|
web server. For example, to create a new directory named uploads and grant
|
||||||
|
write permissions, use the following commands on a Unix/Linux command
|
||||||
|
line:
|
||||||
|
|
||||||
|
mkdir uploads
|
||||||
|
chmod a+w uploads
|
||||||
|
|
||||||
|
b. Navigate to Administration > Configuration > Media > File system, and
|
||||||
|
enter the desired path. Note that if you want to use private file storage,
|
||||||
|
you need to first enter the path for private files and save the
|
||||||
|
configuration, and then change the "Default download method" setting and
|
||||||
|
save again.
|
||||||
|
|
||||||
|
Changing the file system path after files have been uploaded may cause
|
||||||
|
unexpected problems on an existing site. If you modify the file system path
|
||||||
|
on an existing site, remember to copy all files from the original location
|
||||||
|
to the new location.
|
||||||
|
|
||||||
|
7. Revoke documentation file permissions (optional).
|
||||||
|
|
||||||
|
Some administrators suggest making the documentation files, especially
|
||||||
|
CHANGELOG.txt, non-readable so that the exact version of Drupal you are
|
||||||
|
running is slightly more difficult to determine. If you wish to implement
|
||||||
|
this optional security measure, from a Unix/Linux command line you can use
|
||||||
|
the following command:
|
||||||
|
|
||||||
|
chmod a-r CHANGELOG.txt
|
||||||
|
|
||||||
|
Note that the example only affects CHANGELOG.txt. To completely hide all
|
||||||
|
documentation files from public view, repeat this command for each of the
|
||||||
|
Drupal documentation files in the installation directory, substituting the
|
||||||
|
name of each file for CHANGELOG.txt in the example.
|
||||||
|
|
||||||
|
For more information on setting file permissions, see "Modifying Linux,
|
||||||
|
Unix, and Mac file permissions" (http://drupal.org/node/202483) or
|
||||||
|
"Modifying Windows file permissions" (http://drupal.org/node/202491) in the
|
||||||
|
Drupal.org online documentation.
|
||||||
|
|
||||||
|
8. Set up independent "cron" maintenance jobs.
|
||||||
|
|
||||||
|
Many Drupal modules have tasks that must be run periodically, including the
|
||||||
|
Search module (building and updating the index used for keyword searching),
|
||||||
|
the Aggregator module (retrieving feeds from other sites), and the System
|
||||||
|
module (performing routine maintenance and pruning of database tables). These
|
||||||
|
tasks are known as "cron maintenance tasks", named after the Unix/Linux
|
||||||
|
"cron" utility.
|
||||||
|
|
||||||
|
When you install Drupal, its built-in cron feature is enabled, which
|
||||||
|
automatically runs the cron tasks periodically, triggered by people visiting
|
||||||
|
pages of your site. You can configure the built-in cron feature by navigating
|
||||||
|
to Administration > Configuration > System > Cron.
|
||||||
|
|
||||||
|
It is also possible to run the cron tasks independent of site visits; this is
|
||||||
|
recommended for most sites. To do this, you will need to set up an automated
|
||||||
|
process to visit the page cron.php on your site, which executes the cron
|
||||||
|
tasks.
|
||||||
|
|
||||||
|
The URL of the cron.php page requires a "cron key" to protect against
|
||||||
|
unauthorized access. Your site's cron key is automatically generated during
|
||||||
|
installation and is specific to your site. The full URL of the page, with the
|
||||||
|
cron key, is available in the "Cron maintenance tasks" section of the Status
|
||||||
|
report page at Administration > Reports > Status report.
|
||||||
|
|
||||||
|
As an example for how to set up this automated process, you can use the
|
||||||
|
crontab utility on Unix/Linux systems. The following crontab line uses the
|
||||||
|
wget command to visit the cron.php page, and runs each hour, on the hour:
|
||||||
|
|
||||||
|
0 * * * * wget -O - -q -t 1 http://example.com/cron.php?cron_key=YOURKEY
|
||||||
|
|
||||||
|
Replace the text "http://example.com/cron.php?cron_key=YOURKEY" in the
|
||||||
|
example with the full URL displayed under "Cron maintenance tasks" on the
|
||||||
|
"Status report" page.
|
||||||
|
|
||||||
|
More information about cron maintenance tasks is available at
|
||||||
|
http://drupal.org/cron, and sample cron shell scripts can be found in the
|
||||||
|
scripts/ directory. (Note that these scripts must be customized like the
|
||||||
|
above example, to add your site-specific cron key and domain name.)
|
||||||
|
|
||||||
|
BUILDING AND CUSTOMIZING YOUR SITE
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
A new installation of Drupal defaults to a very basic configuration. To extend
|
||||||
|
your site, you use "modules" and "themes". A module is a plugin that adds
|
||||||
|
functionality to Drupal, while a theme changes the look of your site. The core
|
||||||
|
of Drupal provides several optional modules and themes, and you can download
|
||||||
|
more at http://drupal.org/project/modules and http://drupal.org/project/themes
|
||||||
|
|
||||||
|
Do not mix downloaded or custom modules and themes with Drupal's core modules
|
||||||
|
and themes. Drupal's modules and themes are located in the top-level modules and
|
||||||
|
themes directories, while the modules and themes you add to Drupal are normally
|
||||||
|
placed in the sites/all/modules and sites/all/themes directories. If you run a
|
||||||
|
multisite installation, you can also place modules and themes in the
|
||||||
|
site-specific directories -- see the Multisite Configuration section, below.
|
||||||
|
|
||||||
|
Never edit Drupal's core modules and themes; instead, use the hooks available in
|
||||||
|
the Drupal API. To modify the behavior of Drupal, develop a module as described
|
||||||
|
at http://drupal.org/developing/modules. To modify the look of Drupal, create a
|
||||||
|
subtheme as described at http://drupal.org/node/225125, or a completely new
|
||||||
|
theme as described at http://drupal.org/documentation/theme
|
||||||
|
|
||||||
|
MULTISITE CONFIGURATION
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
A single Drupal installation can host several Drupal-powered sites, each with
|
||||||
|
its own individual configuration.
|
||||||
|
|
||||||
|
Additional site configurations are created in subdirectories within the 'sites'
|
||||||
|
directory. Each subdirectory must have a 'settings.php' file, which specifies
|
||||||
|
the configuration settings. The easiest way to create additional sites is to
|
||||||
|
copy the 'default' directory and modify the 'settings.php' file as appropriate.
|
||||||
|
The new directory name is constructed from the site's URL. The configuration for
|
||||||
|
www.example.com could be in 'sites/example.com/settings.php' (note that 'www.'
|
||||||
|
should be omitted if users can access your site at http://example.com/).
|
||||||
|
|
||||||
|
Sites do not have to have a different domain. You can also use subdomains and
|
||||||
|
subdirectories for Drupal sites. For example, example.com, sub.example.com, and
|
||||||
|
sub.example.com/site3 can all be defined as independent Drupal sites. The setup
|
||||||
|
for a configuration such as this would look like the following:
|
||||||
|
|
||||||
|
sites/default/settings.php
|
||||||
|
sites/example.com/settings.php
|
||||||
|
sites/sub.example.com/settings.php
|
||||||
|
sites/sub.example.com.site3/settings.php
|
||||||
|
|
||||||
|
When searching for a site configuration (for example www.sub.example.com/site3),
|
||||||
|
Drupal will search for configuration files in the following order, using the
|
||||||
|
first configuration it finds:
|
||||||
|
|
||||||
|
sites/www.sub.example.com.site3/settings.php
|
||||||
|
sites/sub.example.com.site3/settings.php
|
||||||
|
sites/example.com.site3/settings.php
|
||||||
|
sites/www.sub.example.com/settings.php
|
||||||
|
sites/sub.example.com/settings.php
|
||||||
|
sites/example.com/settings.php
|
||||||
|
sites/default/settings.php
|
||||||
|
|
||||||
|
If you are installing on a non-standard port, the port number is treated as the
|
||||||
|
deepest subdomain. For example: http://www.example.com:8080/ could be loaded
|
||||||
|
from sites/8080.www.example.com/. The port number will be removed according to
|
||||||
|
the pattern above if no port-specific configuration is found, just like a real
|
||||||
|
subdomain.
|
||||||
|
|
||||||
|
Each site configuration can have its own site-specific modules and themes in
|
||||||
|
addition to those installed in the standard 'modules' and 'themes' directories.
|
||||||
|
To use site-specific modules or themes, simply create a 'modules' or 'themes'
|
||||||
|
directory within the site configuration directory. For example, if
|
||||||
|
sub.example.com has a custom theme and a custom module that should not be
|
||||||
|
accessible to other sites, the setup would look like this:
|
||||||
|
|
||||||
|
sites/sub.example.com/
|
||||||
|
settings.php
|
||||||
|
themes/custom_theme
|
||||||
|
modules/custom_module
|
||||||
|
|
||||||
|
NOTE: for more information about multiple virtual hosts or the configuration
|
||||||
|
settings, consult http://drupal.org/getting-started/6/install/multi-site
|
||||||
|
|
||||||
|
For more information on configuring Drupal's file system path in a multisite
|
||||||
|
configuration, see step 6 above.
|
||||||
|
|
||||||
|
MORE INFORMATION
|
||||||
|
----------------
|
||||||
|
|
||||||
|
- See the Drupal.org online documentation:
|
||||||
|
http://drupal.org/documentation
|
||||||
|
|
||||||
|
- For a list of security announcements, see the "Security advisories" page at
|
||||||
|
http://drupal.org/security (available as an RSS feed). This page also
|
||||||
|
describes how to subscribe to these announcements via e-mail.
|
||||||
|
|
||||||
|
- For information about the Drupal security process, or to find out how to
|
||||||
|
report a potential security issue to the Drupal security team, see the
|
||||||
|
"Security team" page at http://drupal.org/security-team
|
||||||
|
|
||||||
|
- For information about the wide range of available support options, visit
|
||||||
|
http://drupal.org and click on Community and Support in the top or bottom
|
||||||
|
navigation.
|
||||||
Executable → Regular
+2
-5
@@ -11,10 +11,8 @@ The Drupal Core branch maintainers oversee the development of Drupal as a whole.
|
|||||||
The branch maintainers for Drupal 7 are:
|
The branch maintainers for Drupal 7 are:
|
||||||
|
|
||||||
- Dries Buytaert 'dries' https://www.drupal.org/u/dries
|
- Dries Buytaert 'dries' https://www.drupal.org/u/dries
|
||||||
- Angela Byron 'webchick' https://www.drupal.org/u/webchick
|
|
||||||
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
|
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
|
||||||
- David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein
|
- (provisional) Drew Webber 'mcdruid' https://www.drupal.org/u/mcdruid
|
||||||
- Stefan Ruijsenaars 'stefan.r' https://www.drupal.org/u/stefanr-0
|
|
||||||
|
|
||||||
|
|
||||||
Component maintainers
|
Component maintainers
|
||||||
@@ -44,10 +42,9 @@ Cron system
|
|||||||
- Derek Wright 'dww' https://www.drupal.org/u/dww
|
- Derek Wright 'dww' https://www.drupal.org/u/dww
|
||||||
|
|
||||||
Database system
|
Database system
|
||||||
- Larry Garfield 'Crell' https://www.drupal.org/u/crell
|
- ?
|
||||||
|
|
||||||
- MySQL driver
|
- MySQL driver
|
||||||
- Larry Garfield 'Crell' https://www.drupal.org/u/crell
|
|
||||||
- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
|
- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
|
||||||
|
|
||||||
- PostgreSQL driver
|
- PostgreSQL driver
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# Core Patches :
|
||||||
|
- Implement language aware tokens for one time login link and cancel link
|
||||||
|
https://www.drupal.org/node/1754162
|
||||||
|
|
||||||
|
//- est-ce que je dois faire ce patch ???
|
||||||
|
//includes/entity.inc
|
||||||
|
//see https://www.drupal.org/node/1003788
|
||||||
|
|
||||||
|
# Modules :
|
||||||
|
Redis
|
||||||
|
- https://www.drupal.org/project/redis/issues/3074189
|
||||||
|
cer
|
||||||
|
contentadminrelink
|
||||||
|
entityreference
|
||||||
|
feedback
|
||||||
|
filter_path_alias
|
||||||
|
flag_lists
|
||||||
|
- https://www.drupal.org/project/flag_lists/issues/2114731
|
||||||
|
login_tobogan (pd with field permission et donc field collection)
|
||||||
|
- https://www.drupal.org/node/1365764#comment-10286257
|
||||||
|
- logintoboggan-exempting_lt_preauth_role_from_user_permissions_js-1365764-52.patch
|
||||||
|
- interdiff-1365764-23-52-do-not-test.diff
|
||||||
|
node_export :
|
||||||
|
- https://www.drupal.org/node/1869918
|
||||||
|
- https://www.drupal.org/node/1911638
|
||||||
|
termreferencetree
|
||||||
|
?? views
|
||||||
|
views_rss_media
|
||||||
|
- https://www.drupal.org/node/2472409
|
||||||
|
- https://www.drupal.org/project/views_rss_media/issues/2149287
|
||||||
|
wysiwyg
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
# Core Patches :
|
|
||||||
- Implement language aware tokens for one time login link and cancel link
|
|
||||||
https://www.drupal.org/node/1754162
|
|
||||||
|
|
||||||
//- est-ce que je dois faire ce patch ???
|
|
||||||
//includes/entity.inc
|
|
||||||
//see https://www.drupal.org/node/1003788
|
|
||||||
|
|
||||||
|
|
||||||
# Modules :
|
|
||||||
|
|
||||||
link : allow any tld (https://www.drupal.org/node/2299657#comment-11414075)
|
|
||||||
cer
|
|
||||||
contentadminrelink
|
|
||||||
// entity_translation_search_api
|
|
||||||
entityreference
|
|
||||||
feedback
|
|
||||||
// field_group
|
|
||||||
filter_path_alias
|
|
||||||
// flag_lists
|
|
||||||
// nodeformcols
|
|
||||||
// search_api
|
|
||||||
// search_api_page
|
|
||||||
// search_api_solr
|
|
||||||
termreferencetree
|
|
||||||
views
|
|
||||||
wysiwyg
|
|
||||||
views_rss_media
|
|
||||||
node_export :
|
|
||||||
- https://www.drupal.org/node/1869918
|
|
||||||
- https://www.drupal.org/node/1911638
|
|
||||||
login_tobogan (pd with field permission et donc field collection)
|
|
||||||
- https://www.drupal.org/node/1365764#comment-10286257
|
|
||||||
- logintoboggan-exempting_lt_preauth_role_from_user_permissions_js-1365764-52.patch
|
|
||||||
- interdiff-1365764-23-52-do-not-test.diff
|
|
||||||
Executable → Regular
Executable → Regular
Executable → Regular
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"drush/drush": "8.*"
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"installer-paths": {
|
||||||
|
"core": ["type:drupal-core"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+1354
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
|||||||
|
diff --git a/flag_lists.module b/flag_lists.module
|
||||||
|
index d829113..b3c04f0 100644
|
||||||
|
--- a/flag_lists.module
|
||||||
|
+++ b/flag_lists.module
|
||||||
|
@@ -1587,6 +1587,32 @@ function flag_lists_fix_link(&$link, $action) {
|
||||||
|
return $fcid;
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Remove all entries of entity_id and type
|
||||||
|
+ *
|
||||||
|
+ * @param $entity_id
|
||||||
|
+ * Entity id which has been flagged.
|
||||||
|
+ * @param $type
|
||||||
|
+ * The entity type.
|
||||||
|
+ */
|
||||||
|
+ function _flag_lists_remove_entity($entity_id, $type) {
|
||||||
|
+ $query = db_select('flag_lists_content')
|
||||||
|
+ ->condition('entity_id', $entity_id)
|
||||||
|
+ ->condition('entity_type', $type);
|
||||||
|
+ $query->fields('flag_lists_content', array('fcid', 'fid', 'uid', 'sid'));
|
||||||
|
+ $items = $query->execute()->fetchAll();
|
||||||
|
+
|
||||||
|
+ if ($items) {
|
||||||
|
+ foreach ($items as $key => $value) {
|
||||||
|
+ db_delete('flag_lists_content')
|
||||||
|
+ ->condition('fcid', $value->fcid)
|
||||||
|
+ ->execute();
|
||||||
|
+ watchdog('flag_lists', t('Deleted entry @fcid from flat_lists_content', array('@fcid' => $value->fcid)));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Updates the flag count for this content
|
||||||
|
*/
|
||||||
|
@@ -1766,3 +1792,17 @@ function flag_lists_views_form_substitutions() {
|
||||||
|
$select_all_placeholder => drupal_render($select_all),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Implements hook_entity_delete
|
||||||
|
+ */
|
||||||
|
+function flag_lists_entity_delete($entity, $type) {
|
||||||
|
+ foreach (flag_get_flags($type) as $flag) {
|
||||||
|
+ if (isset($entity->vid)) {
|
||||||
|
+ $items = _flag_lists_remove_entity($entity->vid, $type);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
Executable → Regular
Executable → Regular
+1
@@ -294,6 +294,7 @@ function ajax_render($commands = array()) {
|
|||||||
|
|
||||||
// Now add a command to merge changes and additions to Drupal.settings.
|
// Now add a command to merge changes and additions to Drupal.settings.
|
||||||
$scripts = drupal_add_js();
|
$scripts = drupal_add_js();
|
||||||
|
drupal_alter('js', $scripts);
|
||||||
if (!empty($scripts['settings'])) {
|
if (!empty($scripts['settings'])) {
|
||||||
$settings = $scripts['settings'];
|
$settings = $scripts['settings'];
|
||||||
array_unshift($commands, ajax_command_settings(drupal_array_merge_deep_array($settings['data']), TRUE));
|
array_unshift($commands, ajax_command_settings(drupal_array_merge_deep_array($settings['data']), TRUE));
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
Executable → Regular
+7
-8
@@ -478,18 +478,17 @@ function _batch_finished() {
|
|||||||
$queue->deleteQueue();
|
$queue->deleteQueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Clean-up the session. Not needed for CLI updates.
|
||||||
|
if (isset($_SESSION)) {
|
||||||
|
unset($_SESSION['batches'][$batch['id']]);
|
||||||
|
if (empty($_SESSION['batches'])) {
|
||||||
|
unset($_SESSION['batches']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$_batch = $batch;
|
$_batch = $batch;
|
||||||
$batch = NULL;
|
$batch = NULL;
|
||||||
|
|
||||||
// Clean-up the session. Not needed for CLI updates.
|
|
||||||
if (isset($_SESSION)) {
|
|
||||||
unset($_SESSION['batches'][$batch['id']]);
|
|
||||||
if (empty($_SESSION['batches'])) {
|
|
||||||
unset($_SESSION['batches']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Redirect if needed.
|
// Redirect if needed.
|
||||||
if ($_batch['progressive']) {
|
if ($_batch['progressive']) {
|
||||||
// Revert the 'destination' that was saved in batch_process().
|
// Revert the 'destination' that was saved in batch_process().
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
+51
-8
@@ -8,7 +8,7 @@
|
|||||||
/**
|
/**
|
||||||
* The current system version.
|
* The current system version.
|
||||||
*/
|
*/
|
||||||
define('VERSION', '7.51');
|
define('VERSION', '7.73');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core API compatibility.
|
* Core API compatibility.
|
||||||
@@ -254,8 +254,13 @@ define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
|
|||||||
* http://tools.ietf.org/html/rfc7231#section-7.1.1.1
|
* http://tools.ietf.org/html/rfc7231#section-7.1.1.1
|
||||||
*
|
*
|
||||||
* Example: Sun, 06 Nov 1994 08:49:37 GMT
|
* Example: Sun, 06 Nov 1994 08:49:37 GMT
|
||||||
|
*
|
||||||
|
* This constant was introduced in PHP 7.0.19 and PHP 7.1.5 but needs to be
|
||||||
|
* defined by Drupal for earlier PHP versions.
|
||||||
*/
|
*/
|
||||||
define('DATE_RFC7231', 'D, d M Y H:i:s \G\M\T');
|
if (!defined('DATE_RFC7231')) {
|
||||||
|
define('DATE_RFC7231', 'D, d M Y H:i:s \G\M\T');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a caching wrapper to be used in place of large array structures.
|
* Provides a caching wrapper to be used in place of large array structures.
|
||||||
@@ -699,6 +704,19 @@ function drupal_environment_initialize() {
|
|||||||
// Set sane locale settings, to ensure consistent string, dates, times and
|
// Set sane locale settings, to ensure consistent string, dates, times and
|
||||||
// numbers handling.
|
// numbers handling.
|
||||||
setlocale(LC_ALL, 'C');
|
setlocale(LC_ALL, 'C');
|
||||||
|
|
||||||
|
// PHP's built-in phar:// stream wrapper is not sufficiently secure. Override
|
||||||
|
// it with a more secure one, which requires PHP 5.3.3. For lower versions,
|
||||||
|
// unregister the built-in one without replacing it. Sites needing phar
|
||||||
|
// support for lower PHP versions must implement hook_stream_wrappers() to
|
||||||
|
// register their desired implementation.
|
||||||
|
if (in_array('phar', stream_get_wrappers(), TRUE)) {
|
||||||
|
stream_wrapper_unregister('phar');
|
||||||
|
if (version_compare(PHP_VERSION, '5.3.3', '>=')) {
|
||||||
|
include_once DRUPAL_ROOT . '/includes/file.phar.inc';
|
||||||
|
file_register_phar_wrapper();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -718,6 +736,16 @@ function drupal_valid_http_host($host) {
|
|||||||
&& preg_match('/^\[?(?:[a-zA-Z0-9-:\]_]+\.?)+$/', $host);
|
&& preg_match('/^\[?(?:[a-zA-Z0-9-:\]_]+\.?)+$/', $host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether an HTTPS request is being served.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* TRUE if the request is HTTPS, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
function drupal_is_https() {
|
||||||
|
return isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the base URL, cookie domain, and session name from configuration.
|
* Sets the base URL, cookie domain, and session name from configuration.
|
||||||
*/
|
*/
|
||||||
@@ -731,7 +759,7 @@ function drupal_settings_initialize() {
|
|||||||
if (file_exists(DRUPAL_ROOT . '/' . conf_path() . '/settings.php')) {
|
if (file_exists(DRUPAL_ROOT . '/' . conf_path() . '/settings.php')) {
|
||||||
include_once DRUPAL_ROOT . '/' . conf_path() . '/settings.php';
|
include_once DRUPAL_ROOT . '/' . conf_path() . '/settings.php';
|
||||||
}
|
}
|
||||||
$is_https = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on';
|
$is_https = drupal_is_https();
|
||||||
|
|
||||||
if (isset($base_url)) {
|
if (isset($base_url)) {
|
||||||
// Parse fixed base URL from settings.php.
|
// Parse fixed base URL from settings.php.
|
||||||
@@ -1970,7 +1998,7 @@ function watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NO
|
|||||||
|
|
||||||
// It is possible that the error handling will itself trigger an error. In that case, we could
|
// It is possible that the error handling will itself trigger an error. In that case, we could
|
||||||
// end up in an infinite loop. To avoid that, we implement a simple static semaphore.
|
// end up in an infinite loop. To avoid that, we implement a simple static semaphore.
|
||||||
if (!$in_error_state && function_exists('module_implements')) {
|
if (!$in_error_state && function_exists('module_invoke_all')) {
|
||||||
$in_error_state = TRUE;
|
$in_error_state = TRUE;
|
||||||
|
|
||||||
// The user object may not exist in all conditions, so 0 is substituted if needed.
|
// The user object may not exist in all conditions, so 0 is substituted if needed.
|
||||||
@@ -1993,9 +2021,7 @@ function watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NO
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Call the logging hooks to log/process the message
|
// Call the logging hooks to log/process the message
|
||||||
foreach (module_implements('watchdog') as $module) {
|
module_invoke_all('watchdog', $log_entry);
|
||||||
module_invoke($module, 'watchdog', $log_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// It is critical that the semaphore is only cleared here, in the parent
|
// It is critical that the semaphore is only cleared here, in the parent
|
||||||
// watchdog() call (not outside the loop), to prevent recursive execution.
|
// watchdog() call (not outside the loop), to prevent recursive execution.
|
||||||
@@ -2490,6 +2516,7 @@ function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
|
|||||||
|
|
||||||
switch ($current_phase) {
|
switch ($current_phase) {
|
||||||
case DRUPAL_BOOTSTRAP_CONFIGURATION:
|
case DRUPAL_BOOTSTRAP_CONFIGURATION:
|
||||||
|
require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc';
|
||||||
_drupal_bootstrap_configuration();
|
_drupal_bootstrap_configuration();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2594,6 +2621,10 @@ function _drupal_exception_handler($exception) {
|
|||||||
_drupal_log_error(_drupal_decode_exception($exception), TRUE);
|
_drupal_log_error(_drupal_decode_exception($exception), TRUE);
|
||||||
}
|
}
|
||||||
catch (Exception $exception2) {
|
catch (Exception $exception2) {
|
||||||
|
// Add a 500 status code in case an exception was thrown before the 500
|
||||||
|
// status could be set (e.g. while loading a maintenance theme from cache).
|
||||||
|
drupal_add_http_header('Status', '500 Internal Server Error');
|
||||||
|
|
||||||
// Another uncaught exception was thrown while handling the first one.
|
// Another uncaught exception was thrown while handling the first one.
|
||||||
// If we are displaying errors, then do so with no possibility of a further uncaught exception being thrown.
|
// If we are displaying errors, then do so with no possibility of a further uncaught exception being thrown.
|
||||||
if (error_displayable()) {
|
if (error_displayable()) {
|
||||||
@@ -2617,6 +2648,9 @@ function _drupal_bootstrap_configuration() {
|
|||||||
timer_start('page');
|
timer_start('page');
|
||||||
// Initialize the configuration, including variables from settings.php.
|
// Initialize the configuration, including variables from settings.php.
|
||||||
drupal_settings_initialize();
|
drupal_settings_initialize();
|
||||||
|
|
||||||
|
// Sanitize unsafe keys from the request.
|
||||||
|
DrupalRequestSanitizer::sanitize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2759,6 +2793,11 @@ function _drupal_bootstrap_variables() {
|
|||||||
unset($_GET['destination']);
|
unset($_GET['destination']);
|
||||||
unset($_REQUEST['destination']);
|
unset($_REQUEST['destination']);
|
||||||
}
|
}
|
||||||
|
// Use the DrupalRequestSanitizer to ensure that the destination's query
|
||||||
|
// parameters are not dangerous.
|
||||||
|
if (isset($_GET['destination'])) {
|
||||||
|
DrupalRequestSanitizer::cleanDestination();
|
||||||
|
}
|
||||||
// If there's still something in $_REQUEST['destination'] that didn't come
|
// If there's still something in $_REQUEST['destination'] that didn't come
|
||||||
// from $_GET, check it too.
|
// from $_GET, check it too.
|
||||||
if (isset($_REQUEST['destination']) && (!isset($_GET['destination']) || $_REQUEST['destination'] != $_GET['destination']) && url_is_external($_REQUEST['destination'])) {
|
if (isset($_REQUEST['destination']) && (!isset($_GET['destination']) || $_REQUEST['destination'] != $_GET['destination']) && url_is_external($_REQUEST['destination'])) {
|
||||||
@@ -3761,8 +3800,12 @@ function _drupal_shutdown_function() {
|
|||||||
chdir(DRUPAL_ROOT);
|
chdir(DRUPAL_ROOT);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (list($key, $callback) = each($callbacks)) {
|
// Manually iterate over the array instead of using a foreach loop.
|
||||||
|
// A foreach operates on a copy of the array, so any shutdown functions that
|
||||||
|
// were added from other shutdown functions would never be called.
|
||||||
|
while ($callback = current($callbacks)) {
|
||||||
call_user_func_array($callback['callback'], $callback['arguments']);
|
call_user_func_array($callback['callback'], $callback['arguments']);
|
||||||
|
next($callbacks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception $exception) {
|
catch (Exception $exception) {
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
+12
-2
@@ -122,7 +122,12 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
|
|||||||
* the administrator panel.
|
* the administrator panel.
|
||||||
* - cache_path: Stores the system paths that have an alias.
|
* - cache_path: Stores the system paths that have an alias.
|
||||||
* @param $expire
|
* @param $expire
|
||||||
* (optional) One of the following values:
|
* (optional) Controls the maximum lifetime of this cache entry. Note that
|
||||||
|
* caches might be subject to clearing at any time, so this setting does not
|
||||||
|
* guarantee a minimum lifetime. With this in mind, the cache should not be
|
||||||
|
* used for data that must be kept during a cache clear, like sessions.
|
||||||
|
*
|
||||||
|
* Use one of the following values:
|
||||||
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
||||||
* explicitly told to using cache_clear_all() with a cache ID.
|
* explicitly told to using cache_clear_all() with a cache ID.
|
||||||
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
|
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
|
||||||
@@ -262,7 +267,12 @@ interface DrupalCacheInterface {
|
|||||||
* 1MB in size to be stored by default. When caching large arrays or
|
* 1MB in size to be stored by default. When caching large arrays or
|
||||||
* similar, take care to ensure $data does not exceed this size.
|
* similar, take care to ensure $data does not exceed this size.
|
||||||
* @param $expire
|
* @param $expire
|
||||||
* (optional) One of the following values:
|
* (optional) Controls the maximum lifetime of this cache entry. Note that
|
||||||
|
* caches might be subject to clearing at any time, so this setting does not
|
||||||
|
* guarantee a minimum lifetime. With this in mind, the cache should not be
|
||||||
|
* used for data that must be kept during a cache clear, like sessions.
|
||||||
|
*
|
||||||
|
* Use one of the following values:
|
||||||
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
* - CACHE_PERMANENT: Indicates that the item should never be removed unless
|
||||||
* explicitly told to using cache_clear_all() with a cache ID.
|
* explicitly told to using cache_clear_all() with a cache ID.
|
||||||
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
|
* - CACHE_TEMPORARY: Indicates that the item should be removed at the next
|
||||||
|
|||||||
Executable → Regular
+136
-52
@@ -391,7 +391,7 @@ function drupal_add_feed($url = NULL, $title = '') {
|
|||||||
*/
|
*/
|
||||||
function drupal_get_feeds($delimiter = "\n") {
|
function drupal_get_feeds($delimiter = "\n") {
|
||||||
$feeds = drupal_add_feed();
|
$feeds = drupal_add_feed();
|
||||||
return implode($feeds, $delimiter);
|
return implode($delimiter, $feeds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -487,7 +487,7 @@ function drupal_http_build_query(array $query, $parent = '') {
|
|||||||
$params = array();
|
$params = array();
|
||||||
|
|
||||||
foreach ($query as $key => $value) {
|
foreach ($query as $key => $value) {
|
||||||
$key = ($parent ? $parent . '[' . rawurlencode($key) . ']' : rawurlencode($key));
|
$key = $parent ? $parent . rawurlencode('[' . $key . ']') : rawurlencode($key);
|
||||||
|
|
||||||
// Recurse into children.
|
// Recurse into children.
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
@@ -611,8 +611,9 @@ function drupal_parse_url($url) {
|
|||||||
}
|
}
|
||||||
// The 'q' parameter contains the path of the current page if clean URLs are
|
// The 'q' parameter contains the path of the current page if clean URLs are
|
||||||
// disabled. It overrides the 'path' of the URL when present, even if clean
|
// disabled. It overrides the 'path' of the URL when present, even if clean
|
||||||
// URLs are enabled, due to how Apache rewriting rules work.
|
// URLs are enabled, due to how Apache rewriting rules work. The path
|
||||||
if (isset($options['query']['q'])) {
|
// parameter must be a string.
|
||||||
|
if (isset($options['query']['q']) && is_string($options['query']['q'])) {
|
||||||
$options['path'] = $options['query']['q'];
|
$options['path'] = $options['query']['q'];
|
||||||
unset($options['query']['q']);
|
unset($options['query']['q']);
|
||||||
}
|
}
|
||||||
@@ -683,7 +684,10 @@ function drupal_goto($path = '', array $options = array(), $http_response_code =
|
|||||||
// We do not allow absolute URLs to be passed via $_GET, as this can be an attack vector.
|
// We do not allow absolute URLs to be passed via $_GET, as this can be an attack vector.
|
||||||
if (isset($_GET['destination']) && !url_is_external($_GET['destination'])) {
|
if (isset($_GET['destination']) && !url_is_external($_GET['destination'])) {
|
||||||
$destination = drupal_parse_url($_GET['destination']);
|
$destination = drupal_parse_url($_GET['destination']);
|
||||||
$path = $destination['path'];
|
// Double check the path derived by drupal_parse_url() is not external.
|
||||||
|
if (!url_is_external($destination['path'])) {
|
||||||
|
$path = $destination['path'];
|
||||||
|
}
|
||||||
$options['query'] = $destination['query'];
|
$options['query'] = $destination['query'];
|
||||||
$options['fragment'] = $destination['fragment'];
|
$options['fragment'] = $destination['fragment'];
|
||||||
}
|
}
|
||||||
@@ -759,9 +763,10 @@ function drupal_access_denied() {
|
|||||||
* (optional) An array that can have one or more of the following elements:
|
* (optional) An array that can have one or more of the following elements:
|
||||||
* - headers: An array containing request headers to send as name/value pairs.
|
* - headers: An array containing request headers to send as name/value pairs.
|
||||||
* - method: A string containing the request method. Defaults to 'GET'.
|
* - method: A string containing the request method. Defaults to 'GET'.
|
||||||
* - data: A string containing the request body, formatted as
|
* - data: An array containing the values for the request body or a string
|
||||||
* 'param=value¶m=value&...'; to generate this, use http_build_query().
|
* containing the request body, formatted as
|
||||||
* Defaults to NULL.
|
* 'param=value¶m=value&...'; to generate this, use
|
||||||
|
* drupal_http_build_query(). Defaults to NULL.
|
||||||
* - max_redirects: An integer representing how many times a redirect
|
* - max_redirects: An integer representing how many times a redirect
|
||||||
* may be followed. Defaults to 3.
|
* may be followed. Defaults to 3.
|
||||||
* - timeout: A float representing the maximum number of seconds the function
|
* - timeout: A float representing the maximum number of seconds the function
|
||||||
@@ -787,7 +792,7 @@ function drupal_access_denied() {
|
|||||||
* easy access the array keys are returned in lower case.
|
* easy access the array keys are returned in lower case.
|
||||||
* - data: A string containing the response body that was received.
|
* - data: A string containing the response body that was received.
|
||||||
*
|
*
|
||||||
* @see http_build_query()
|
* @see drupal_http_build_query()
|
||||||
*/
|
*/
|
||||||
function drupal_http_request($url, array $options = array()) {
|
function drupal_http_request($url, array $options = array()) {
|
||||||
// Allow an alternate HTTP client library to replace Drupal's default
|
// Allow an alternate HTTP client library to replace Drupal's default
|
||||||
@@ -866,8 +871,10 @@ function drupal_http_request($url, array $options = array()) {
|
|||||||
// Make the socket connection to a proxy server.
|
// Make the socket connection to a proxy server.
|
||||||
$socket = 'tcp://' . $proxy_server . ':' . variable_get('proxy_port', 8080);
|
$socket = 'tcp://' . $proxy_server . ':' . variable_get('proxy_port', 8080);
|
||||||
// The Host header still needs to match the real request.
|
// The Host header still needs to match the real request.
|
||||||
$options['headers']['Host'] = $uri['host'];
|
if (!isset($options['headers']['Host'])) {
|
||||||
$options['headers']['Host'] .= isset($uri['port']) && $uri['port'] != 80 ? ':' . $uri['port'] : '';
|
$options['headers']['Host'] = $uri['host'];
|
||||||
|
$options['headers']['Host'] .= isset($uri['port']) && $uri['port'] != 80 ? ':' . $uri['port'] : '';
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'http':
|
case 'http':
|
||||||
@@ -877,14 +884,18 @@ function drupal_http_request($url, array $options = array()) {
|
|||||||
// RFC 2616: "non-standard ports MUST, default ports MAY be included".
|
// RFC 2616: "non-standard ports MUST, default ports MAY be included".
|
||||||
// We don't add the standard port to prevent from breaking rewrite rules
|
// We don't add the standard port to prevent from breaking rewrite rules
|
||||||
// checking the host that do not take into account the port number.
|
// checking the host that do not take into account the port number.
|
||||||
$options['headers']['Host'] = $uri['host'] . ($port != 80 ? ':' . $port : '');
|
if (!isset($options['headers']['Host'])) {
|
||||||
|
$options['headers']['Host'] = $uri['host'] . ($port != 80 ? ':' . $port : '');
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'https':
|
case 'https':
|
||||||
// Note: Only works when PHP is compiled with OpenSSL support.
|
// Note: Only works when PHP is compiled with OpenSSL support.
|
||||||
$port = isset($uri['port']) ? $uri['port'] : 443;
|
$port = isset($uri['port']) ? $uri['port'] : 443;
|
||||||
$socket = 'ssl://' . $uri['host'] . ':' . $port;
|
$socket = 'ssl://' . $uri['host'] . ':' . $port;
|
||||||
$options['headers']['Host'] = $uri['host'] . ($port != 443 ? ':' . $port : '');
|
if (!isset($options['headers']['Host'])) {
|
||||||
|
$options['headers']['Host'] = $uri['host'] . ($port != 443 ? ':' . $port : '');
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -923,6 +934,11 @@ function drupal_http_request($url, array $options = array()) {
|
|||||||
$path .= '?' . $uri['query'];
|
$path .= '?' . $uri['query'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert array $options['data'] to query string.
|
||||||
|
if (is_array($options['data'])) {
|
||||||
|
$options['data'] = drupal_http_build_query($options['data']);
|
||||||
|
}
|
||||||
|
|
||||||
// Only add Content-Length if we actually have any content or if it is a POST
|
// Only add Content-Length if we actually have any content or if it is a POST
|
||||||
// or PUT request. Some non-standard servers get confused by Content-Length in
|
// or PUT request. Some non-standard servers get confused by Content-Length in
|
||||||
// at least HEAD/GET requests, and Squid always requires Content-Length in
|
// at least HEAD/GET requests, and Squid always requires Content-Length in
|
||||||
@@ -1087,6 +1103,11 @@ function drupal_http_request($url, array $options = array()) {
|
|||||||
elseif ($options['max_redirects']) {
|
elseif ($options['max_redirects']) {
|
||||||
// Redirect to the new location.
|
// Redirect to the new location.
|
||||||
$options['max_redirects']--;
|
$options['max_redirects']--;
|
||||||
|
|
||||||
|
// We need to unset the 'Host' header
|
||||||
|
// as we are redirecting to a new location.
|
||||||
|
unset($options['headers']['Host']);
|
||||||
|
|
||||||
$result = drupal_http_request($location, $options);
|
$result = drupal_http_request($location, $options);
|
||||||
$result->redirect_code = $code;
|
$result->redirect_code = $code;
|
||||||
}
|
}
|
||||||
@@ -2236,8 +2257,11 @@ function url($path = NULL, array $options = array()) {
|
|||||||
'prefix' => ''
|
'prefix' => ''
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Determine whether this is an external link, but ensure that the current
|
||||||
|
// path is always treated as internal by default (to prevent external link
|
||||||
|
// injection vulnerabilities).
|
||||||
if (!isset($options['external'])) {
|
if (!isset($options['external'])) {
|
||||||
$options['external'] = url_is_external($path);
|
$options['external'] = $path === $_GET['q'] ? FALSE : url_is_external($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preserve the original path before altering or aliasing.
|
// Preserve the original path before altering or aliasing.
|
||||||
@@ -2307,7 +2331,10 @@ function url($path = NULL, array $options = array()) {
|
|||||||
$language = isset($options['language']) && isset($options['language']->language) ? $options['language']->language : '';
|
$language = isset($options['language']) && isset($options['language']->language) ? $options['language']->language : '';
|
||||||
$alias = drupal_get_path_alias($original_path, $language);
|
$alias = drupal_get_path_alias($original_path, $language);
|
||||||
if ($alias != $original_path) {
|
if ($alias != $original_path) {
|
||||||
$path = $alias;
|
// Strip leading slashes from internal path aliases to prevent them
|
||||||
|
// becoming external URLs without protocol. /example.com should not be
|
||||||
|
// turned into //example.com.
|
||||||
|
$path = ltrim($alias, '/');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3716,7 +3743,7 @@ function _drupal_build_css_path($matches, $base = NULL) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prefix with base and remove '../' segments where possible.
|
// Prefix with base and remove '../' segments where possible.
|
||||||
$path = $_base . $matches[1];
|
$path = $_base . (isset($matches[1]) ? $matches[1] : '');
|
||||||
$last = '';
|
$last = '';
|
||||||
while ($path != $last) {
|
while ($path != $last) {
|
||||||
$last = $path;
|
$last = $path;
|
||||||
@@ -3986,7 +4013,11 @@ function drupal_html_id($id) {
|
|||||||
// be merged with content already on the base page. The HTML IDs must be
|
// be merged with content already on the base page. The HTML IDs must be
|
||||||
// unique for the fully merged content. Therefore, initialize $seen_ids to
|
// unique for the fully merged content. Therefore, initialize $seen_ids to
|
||||||
// take into account IDs that are already in use on the base page.
|
// take into account IDs that are already in use on the base page.
|
||||||
$seen_ids_init = &drupal_static(__FUNCTION__ . ':init');
|
static $drupal_static_fast;
|
||||||
|
if (!isset($drupal_static_fast['seen_ids_init'])) {
|
||||||
|
$drupal_static_fast['seen_ids_init'] = &drupal_static(__FUNCTION__ . ':init');
|
||||||
|
}
|
||||||
|
$seen_ids_init = &$drupal_static_fast['seen_ids_init'];
|
||||||
if (!isset($seen_ids_init)) {
|
if (!isset($seen_ids_init)) {
|
||||||
// Ideally, Drupal would provide an API to persist state information about
|
// Ideally, Drupal would provide an API to persist state information about
|
||||||
// prior page requests in the database, and we'd be able to add this
|
// prior page requests in the database, and we'd be able to add this
|
||||||
@@ -4031,7 +4062,10 @@ function drupal_html_id($id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$seen_ids = &drupal_static(__FUNCTION__, $seen_ids_init);
|
if (!isset($drupal_static_fast['seen_ids'])) {
|
||||||
|
$drupal_static_fast['seen_ids'] = &drupal_static(__FUNCTION__, $seen_ids_init);
|
||||||
|
}
|
||||||
|
$seen_ids = &$drupal_static_fast['seen_ids'];
|
||||||
|
|
||||||
$id = strtr(drupal_strtolower($id), array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
|
$id = strtr(drupal_strtolower($id), array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
|
||||||
|
|
||||||
@@ -4416,12 +4450,54 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$output = '';
|
// Sort the JavaScript so that it appears in the correct order.
|
||||||
// The index counter is used to keep aggregated and non-aggregated files in
|
uasort($items, 'drupal_sort_css_js');
|
||||||
// order by weight.
|
|
||||||
$index = 1;
|
// Provide the page with information about the individual JavaScript files
|
||||||
$processed = array();
|
// used, information not otherwise available when aggregation is enabled.
|
||||||
$files = array();
|
$setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1);
|
||||||
|
unset($setting['ajaxPageState']['js']['settings']);
|
||||||
|
drupal_add_js($setting, 'setting');
|
||||||
|
|
||||||
|
// If we're outputting the header scope, then this might be the final time
|
||||||
|
// that drupal_get_js() is running, so add the setting to this output as well
|
||||||
|
// as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's
|
||||||
|
// because drupal_get_js() was intentionally passed a $javascript argument
|
||||||
|
// stripped off settings, potentially in order to override how settings get
|
||||||
|
// output, so in this case, do not add the setting to this output.
|
||||||
|
if ($scope == 'header' && isset($items['settings'])) {
|
||||||
|
$items['settings']['data'][] = $setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
$elements = array(
|
||||||
|
'#type' => 'scripts',
|
||||||
|
'#items' => $items,
|
||||||
|
);
|
||||||
|
|
||||||
|
return drupal_render($elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The #pre_render callback for the "scripts" element.
|
||||||
|
*
|
||||||
|
* This callback adds elements needed for <script> tags to be rendered.
|
||||||
|
*
|
||||||
|
* @param array $elements
|
||||||
|
* A render array containing:
|
||||||
|
* - '#items': The JS items as returned by drupal_add_js() and altered by
|
||||||
|
* drupal_get_js().
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* The $elements variable passed as argument with two more children keys:
|
||||||
|
* - "scripts": contains the Javascript items
|
||||||
|
* - "settings": contains the Javascript settings items.
|
||||||
|
* If those keys are already existing, then the items will be appended and
|
||||||
|
* their keys will be preserved.
|
||||||
|
*
|
||||||
|
* @see drupal_get_js()
|
||||||
|
* @see drupal_add_js()
|
||||||
|
*/
|
||||||
|
function drupal_pre_render_scripts(array $elements) {
|
||||||
$preprocess_js = (variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update'));
|
$preprocess_js = (variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update'));
|
||||||
|
|
||||||
// A dummy query-string is added to filenames, to gain control over
|
// A dummy query-string is added to filenames, to gain control over
|
||||||
@@ -4442,34 +4518,29 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
|
|||||||
// third-party code might require the use of a different query string.
|
// third-party code might require the use of a different query string.
|
||||||
$js_version_string = variable_get('drupal_js_version_query_string', 'v=');
|
$js_version_string = variable_get('drupal_js_version_query_string', 'v=');
|
||||||
|
|
||||||
// Sort the JavaScript so that it appears in the correct order.
|
$files = array();
|
||||||
uasort($items, 'drupal_sort_css_js');
|
|
||||||
|
|
||||||
// Provide the page with information about the individual JavaScript files
|
$scripts = isset($elements['scripts']) ? $elements['scripts'] : array();
|
||||||
// used, information not otherwise available when aggregation is enabled.
|
$scripts += array('#weight' => 0);
|
||||||
$setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1);
|
|
||||||
unset($setting['ajaxPageState']['js']['settings']);
|
|
||||||
drupal_add_js($setting, 'setting');
|
|
||||||
|
|
||||||
// If we're outputting the header scope, then this might be the final time
|
$settings = isset($elements['settings']) ? $elements['settings'] : array();
|
||||||
// that drupal_get_js() is running, so add the setting to this output as well
|
$settings += array('#weight' => $scripts['#weight'] + 10);
|
||||||
// as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's
|
|
||||||
// because drupal_get_js() was intentionally passed a $javascript argument
|
// The index counter is used to keep aggregated and non-aggregated files in
|
||||||
// stripped off settings, potentially in order to override how settings get
|
// order by weight. Use existing scripts count as a starting point.
|
||||||
// output, so in this case, do not add the setting to this output.
|
$index = count(element_children($scripts)) + 1;
|
||||||
if ($scope == 'header' && isset($items['settings'])) {
|
|
||||||
$items['settings']['data'][] = $setting;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through the JavaScript to construct the rendered output.
|
// Loop through the JavaScript to construct the rendered output.
|
||||||
$element = array(
|
$element = array(
|
||||||
|
'#type' => 'html_tag',
|
||||||
'#tag' => 'script',
|
'#tag' => 'script',
|
||||||
'#value' => '',
|
'#value' => '',
|
||||||
'#attributes' => array(
|
'#attributes' => array(
|
||||||
'type' => 'text/javascript',
|
'type' => 'text/javascript',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
foreach ($items as $item) {
|
|
||||||
|
foreach ($elements['#items'] as $item) {
|
||||||
$query_string = empty($item['version']) ? $default_query_string : $js_version_string . $item['version'];
|
$query_string = empty($item['version']) ? $default_query_string : $js_version_string . $item['version'];
|
||||||
|
|
||||||
switch ($item['type']) {
|
switch ($item['type']) {
|
||||||
@@ -4478,7 +4549,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
|
|||||||
$js_element['#value_prefix'] = $embed_prefix;
|
$js_element['#value_prefix'] = $embed_prefix;
|
||||||
$js_element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(drupal_array_merge_deep_array($item['data'])) . ");";
|
$js_element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(drupal_array_merge_deep_array($item['data'])) . ");";
|
||||||
$js_element['#value_suffix'] = $embed_suffix;
|
$js_element['#value_suffix'] = $embed_suffix;
|
||||||
$output .= theme('html_tag', array('element' => $js_element));
|
$settings[] = $js_element;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'inline':
|
case 'inline':
|
||||||
@@ -4489,7 +4560,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
|
|||||||
$js_element['#value_prefix'] = $embed_prefix;
|
$js_element['#value_prefix'] = $embed_prefix;
|
||||||
$js_element['#value'] = $item['data'];
|
$js_element['#value'] = $item['data'];
|
||||||
$js_element['#value_suffix'] = $embed_suffix;
|
$js_element['#value_suffix'] = $embed_suffix;
|
||||||
$processed[$index++] = theme('html_tag', array('element' => $js_element));
|
$scripts[$index++] = $js_element;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'file':
|
case 'file':
|
||||||
@@ -4500,7 +4571,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
|
|||||||
}
|
}
|
||||||
$query_string_separator = (strpos($item['data'], '?') !== FALSE) ? '&' : '?';
|
$query_string_separator = (strpos($item['data'], '?') !== FALSE) ? '&' : '?';
|
||||||
$js_element['#attributes']['src'] = file_create_url($item['data']) . $query_string_separator . ($item['cache'] ? $query_string : REQUEST_TIME);
|
$js_element['#attributes']['src'] = file_create_url($item['data']) . $query_string_separator . ($item['cache'] ? $query_string : REQUEST_TIME);
|
||||||
$processed[$index++] = theme('html_tag', array('element' => $js_element));
|
$scripts[$index++] = $js_element;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// By increasing the index for each aggregated file, we maintain
|
// By increasing the index for each aggregated file, we maintain
|
||||||
@@ -4511,7 +4582,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
|
|||||||
// leading to better front-end performance of a website as a whole.
|
// leading to better front-end performance of a website as a whole.
|
||||||
// See drupal_add_js() for details.
|
// See drupal_add_js() for details.
|
||||||
$key = 'aggregate_' . $item['group'] . '_' . $item['every_page'] . '_' . $index;
|
$key = 'aggregate_' . $item['group'] . '_' . $item['every_page'] . '_' . $index;
|
||||||
$processed[$key] = '';
|
$scripts[$key] = '';
|
||||||
$files[$key][$item['data']] = $item;
|
$files[$key][$item['data']] = $item;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -4523,7 +4594,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
|
|||||||
$js_element['#attributes']['defer'] = 'defer';
|
$js_element['#attributes']['defer'] = 'defer';
|
||||||
}
|
}
|
||||||
$js_element['#attributes']['src'] = $item['data'];
|
$js_element['#attributes']['src'] = $item['data'];
|
||||||
$processed[$index++] = theme('html_tag', array('element' => $js_element));
|
$scripts[$index++] = $js_element;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4538,14 +4609,18 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
|
|||||||
$preprocess_file = file_create_url($uri);
|
$preprocess_file = file_create_url($uri);
|
||||||
$js_element = $element;
|
$js_element = $element;
|
||||||
$js_element['#attributes']['src'] = $preprocess_file;
|
$js_element['#attributes']['src'] = $preprocess_file;
|
||||||
$processed[$key] = theme('html_tag', array('element' => $js_element));
|
$scripts[$key] = $js_element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep the order of JS files consistent as some are preprocessed and others are not.
|
// Keep the order of JS files consistent as some are preprocessed and others
|
||||||
// Make sure any inline or JS setting variables appear last after libraries have loaded.
|
// are not. Make sure any inline or JS setting variables appear last after
|
||||||
return implode('', $processed) . $output;
|
// libraries have loaded.
|
||||||
|
$element['scripts'] = $scripts;
|
||||||
|
$element['settings'] = $settings;
|
||||||
|
|
||||||
|
return $element;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6581,7 +6656,7 @@ function element_children(&$elements, $sort = FALSE) {
|
|||||||
$children = array();
|
$children = array();
|
||||||
$sortable = FALSE;
|
$sortable = FALSE;
|
||||||
foreach ($elements as $key => $value) {
|
foreach ($elements as $key => $value) {
|
||||||
if ($key === '' || $key[0] !== '#') {
|
if (is_int($key) || $key === '' || $key[0] !== '#') {
|
||||||
$children[$key] = $value;
|
$children[$key] = $value;
|
||||||
if (is_array($value) && isset($value['#weight'])) {
|
if (is_array($value) && isset($value['#weight'])) {
|
||||||
$sortable = TRUE;
|
$sortable = TRUE;
|
||||||
@@ -6927,7 +7002,16 @@ function drupal_common_theme() {
|
|||||||
'variables' => array(),
|
'variables' => array(),
|
||||||
),
|
),
|
||||||
'table' => array(
|
'table' => array(
|
||||||
'variables' => array('header' => NULL, 'rows' => NULL, 'attributes' => array(), 'caption' => NULL, 'colgroups' => array(), 'sticky' => TRUE, 'empty' => ''),
|
'variables' => array(
|
||||||
|
'header' => NULL,
|
||||||
|
'footer' => NULL,
|
||||||
|
'rows' => NULL,
|
||||||
|
'attributes' => array(),
|
||||||
|
'caption' => NULL,
|
||||||
|
'colgroups' => array(),
|
||||||
|
'sticky' => TRUE,
|
||||||
|
'empty' => '',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
'tablesort_indicator' => array(
|
'tablesort_indicator' => array(
|
||||||
'variables' => array('style' => NULL),
|
'variables' => array('style' => NULL),
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
+6
-6
@@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name by which to obtain a lock for retrive the next insert id.
|
* The name by which to obtain a lock for retrieving the next insert id.
|
||||||
*/
|
*/
|
||||||
define('POSTGRESQL_NEXTID_LOCK', 1000);
|
define('POSTGRESQL_NEXTID_LOCK', 1000);
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
|||||||
$connection_options['pdo'] += array(
|
$connection_options['pdo'] += array(
|
||||||
// Prepared statements are most effective for performance when queries
|
// Prepared statements are most effective for performance when queries
|
||||||
// are recycled (used several times). However, if they are not re-used,
|
// are recycled (used several times). However, if they are not re-used,
|
||||||
// prepared statements become ineffecient. Since most of Drupal's
|
// prepared statements become inefficient. Since most of Drupal's
|
||||||
// prepared queries are not re-used, it should be faster to emulate
|
// prepared queries are not re-used, it should be faster to emulate
|
||||||
// the preparation than to actually ready statements for re-use. If in
|
// the preparation than to actually ready statements for re-use. If in
|
||||||
// doubt, reset to FALSE and measure performance.
|
// doubt, reset to FALSE and measure performance.
|
||||||
@@ -175,14 +175,14 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrive a the next id in a sequence.
|
* Retrieve the next id in a sequence.
|
||||||
*
|
*
|
||||||
* PostgreSQL has built in sequences. We'll use these instead of inserting
|
* PostgreSQL has built in sequences. We'll use these instead of inserting
|
||||||
* and updating a sequences table.
|
* and updating a sequences table.
|
||||||
*/
|
*/
|
||||||
public function nextId($existing = 0) {
|
public function nextId($existing = 0) {
|
||||||
|
|
||||||
// Retrive the name of the sequence. This information cannot be cached
|
// Retrieve the name of the sequence. This information cannot be cached
|
||||||
// because the prefix may change, for example, like it does in simpletests.
|
// because the prefix may change, for example, like it does in simpletests.
|
||||||
$sequence_name = $this->makeSequenceName('sequences', 'value');
|
$sequence_name = $this->makeSequenceName('sequences', 'value');
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL advisory locks are simply locks to be used by an
|
// PostgreSQL advisory locks are simply locks to be used by an
|
||||||
// application such as Drupal. This will prevent other Drupal proccesses
|
// application such as Drupal. This will prevent other Drupal processes
|
||||||
// from altering the sequence while we are.
|
// from altering the sequence while we are.
|
||||||
$this->query("SELECT pg_advisory_lock(" . POSTGRESQL_NEXTID_LOCK . ")");
|
$this->query("SELECT pg_advisory_lock(" . POSTGRESQL_NEXTID_LOCK . ")");
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
|||||||
// Reset the sequence to a higher value than the existing id.
|
// Reset the sequence to a higher value than the existing id.
|
||||||
$this->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1));
|
$this->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1));
|
||||||
|
|
||||||
// Retrive the next id. We know this will be as high as we want it.
|
// Retrieve the next id. We know this will be as high as we want it.
|
||||||
$id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
|
$id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
|
||||||
|
|
||||||
$this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")");
|
$this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")");
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -165,7 +165,7 @@ class DatabaseTasks_pgsql extends DatabaseTasks {
|
|||||||
LANGUAGE \'sql\''
|
LANGUAGE \'sql\''
|
||||||
);
|
);
|
||||||
|
|
||||||
// Using || to concatenate in Drupal is not recommeneded because there are
|
// Using || to concatenate in Drupal is not recommended because there are
|
||||||
// database drivers for Drupal that do not support the syntax, however
|
// database drivers for Drupal that do not support the syntax, however
|
||||||
// they do support CONCAT(item1, item2) which we can replicate in
|
// they do support CONCAT(item1, item2) which we can replicate in
|
||||||
// PostgreSQL. PostgreSQL requires the function to be defined for each
|
// PostgreSQL. PostgreSQL requires the function to be defined for each
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
Executable → Regular
+2
-2
@@ -80,7 +80,7 @@ class SelectQuery_pgsql extends SelectQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If a table loads all fields, it can not be added again. It would
|
// If a table loads all fields, it can not be added again. It would
|
||||||
// result in an ambigious alias error because that field would be loaded
|
// result in an ambiguous alias error because that field would be loaded
|
||||||
// twice: Once through table_alias.* and once directly. If the field
|
// twice: Once through table_alias.* and once directly. If the field
|
||||||
// actually belongs to a different table, it must be added manually.
|
// actually belongs to a different table, it must be added manually.
|
||||||
foreach ($this->tables as $table) {
|
foreach ($this->tables as $table) {
|
||||||
@@ -90,7 +90,7 @@ class SelectQuery_pgsql extends SelectQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If $field contains an characters which are not allowed in a field name
|
// If $field contains an characters which are not allowed in a field name
|
||||||
// it is considered an expression, these can't be handeld automatically
|
// it is considered an expression, these can't be handled automatically
|
||||||
// either.
|
// either.
|
||||||
if ($this->connection->escapeField($field) != $field) {
|
if ($this->connection->escapeField($field) != $field) {
|
||||||
return $return;
|
return $return;
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
+3
-3
@@ -845,8 +845,8 @@ class DeleteQuery extends Query implements QueryConditionInterface {
|
|||||||
/**
|
/**
|
||||||
* Executes the DELETE query.
|
* Executes the DELETE query.
|
||||||
*
|
*
|
||||||
* @return
|
* @return int
|
||||||
* The return value is dependent on the database connection.
|
* The number of rows affected by the delete query.
|
||||||
*/
|
*/
|
||||||
public function execute() {
|
public function execute() {
|
||||||
$values = array();
|
$values = array();
|
||||||
@@ -1242,7 +1242,7 @@ class UpdateQuery extends Query implements QueryConditionInterface {
|
|||||||
* MergeQuery::updateFields() and MergeQuery::insertFields() needs to be called
|
* MergeQuery::updateFields() and MergeQuery::insertFields() needs to be called
|
||||||
* instead. MergeQuery::fields() can also be called which calls both of these
|
* instead. MergeQuery::fields() can also be called which calls both of these
|
||||||
* methods as the common case is to use the same column-value pairs for both
|
* methods as the common case is to use the same column-value pairs for both
|
||||||
* INSERT and UPDATE. However, this is not mandatory. Another convinient
|
* INSERT and UPDATE. However, this is not mandatory. Another convenient
|
||||||
* wrapper is MergeQuery::key() which adds the same column-value pairs to the
|
* wrapper is MergeQuery::key() which adds the same column-value pairs to the
|
||||||
* condition and the INSERT query part.
|
* condition and the INSERT query part.
|
||||||
*
|
*
|
||||||
|
|||||||
Executable → Regular
+4
-1
@@ -164,6 +164,9 @@ require_once dirname(__FILE__) . '/query.inc';
|
|||||||
* @see drupal_install_schema()
|
* @see drupal_install_schema()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for database schema definitions.
|
||||||
|
*/
|
||||||
abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
||||||
|
|
||||||
protected $connection;
|
protected $connection;
|
||||||
@@ -291,7 +294,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
|||||||
protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
|
protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
|
||||||
$info = $this->connection->getConnectionOptions();
|
$info = $this->connection->getConnectionOptions();
|
||||||
|
|
||||||
// Retrive the table name and schema
|
// Retrieve the table name and schema
|
||||||
$table_info = $this->getPrefixInfo($table_name, $add_prefix);
|
$table_info = $this->getPrefixInfo($table_name, $add_prefix);
|
||||||
|
|
||||||
$condition = new DatabaseCondition('AND');
|
$condition = new DatabaseCondition('AND');
|
||||||
|
|||||||
Executable → Regular
+15
@@ -1231,6 +1231,21 @@ class SelectQuery extends Query implements SelectQueryInterface {
|
|||||||
|
|
||||||
// Modules may alter all queries or only those having a particular tag.
|
// Modules may alter all queries or only those having a particular tag.
|
||||||
if (isset($this->alterTags)) {
|
if (isset($this->alterTags)) {
|
||||||
|
// Many contrib modules assume that query tags used for access-checking
|
||||||
|
// purposes follow the pattern $entity_type . '_access'. But this is
|
||||||
|
// not the case for taxonomy terms, since core used to add term_access
|
||||||
|
// instead of taxonomy_term_access to its queries. Provide backwards
|
||||||
|
// compatibility by adding both tags here instead of attempting to fix
|
||||||
|
// all contrib modules in a coordinated effort.
|
||||||
|
// TODO:
|
||||||
|
// - Extract this mechanism into a hook as part of a public (non-security)
|
||||||
|
// issue.
|
||||||
|
// - Emit E_USER_DEPRECATED if term_access is used.
|
||||||
|
// https://www.drupal.org/node/2575081
|
||||||
|
$term_access_tags = array('term_access' => 1, 'taxonomy_term_access' => 1);
|
||||||
|
if (array_intersect_key($this->alterTags, $term_access_tags)) {
|
||||||
|
$this->alterTags += $term_access_tags;
|
||||||
|
}
|
||||||
$hooks = array('query');
|
$hooks = array('query');
|
||||||
foreach ($this->alterTags as $tag => $value) {
|
foreach ($this->alterTags as $tag => $value) {
|
||||||
$hooks[] = 'query_' . $tag;
|
$hooks[] = 'query_' . $tag;
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
Executable → Regular
+6
-7
@@ -99,16 +99,15 @@ class UpdateQuery_sqlite extends UpdateQuery {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* SQLite specific implementation of DeleteQuery.
|
* SQLite specific implementation of DeleteQuery.
|
||||||
*
|
|
||||||
* When the WHERE is omitted from a DELETE statement and the table being deleted
|
|
||||||
* has no triggers, SQLite uses an optimization to erase the entire table content
|
|
||||||
* without having to visit each row of the table individually.
|
|
||||||
*
|
|
||||||
* Prior to SQLite 3.6.5, SQLite does not return the actual number of rows deleted
|
|
||||||
* by that optimized "truncate" optimization.
|
|
||||||
*/
|
*/
|
||||||
class DeleteQuery_sqlite extends DeleteQuery {
|
class DeleteQuery_sqlite extends DeleteQuery {
|
||||||
public function execute() {
|
public function execute() {
|
||||||
|
// When the WHERE is omitted from a DELETE statement and the table being
|
||||||
|
// deleted has no triggers, SQLite uses an optimization to erase the entire
|
||||||
|
// table content without having to visit each row of the table individually.
|
||||||
|
// Prior to SQLite 3.6.5, SQLite does not return the actual number of rows
|
||||||
|
// deleted by that optimized "truncate" optimization. But we want to return
|
||||||
|
// the number of rows affected, so we calculate it directly.
|
||||||
if (!count($this->condition)) {
|
if (!count($this->condition)) {
|
||||||
$total_rows = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($this->table) . '}')->fetchField();
|
$total_rows = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($this->table) . '}')->fetchField();
|
||||||
parent::execute();
|
parent::execute();
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -244,7 +244,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
|||||||
// database. So the syntax '...RENAME TO database.table' would fail.
|
// database. So the syntax '...RENAME TO database.table' would fail.
|
||||||
// So we must determine the full table name here rather than surrounding
|
// So we must determine the full table name here rather than surrounding
|
||||||
// the table with curly braces incase the db_prefix contains a reference
|
// the table with curly braces incase the db_prefix contains a reference
|
||||||
// to a database outside of our existsing database.
|
// to a database outside of our existing database.
|
||||||
$info = $this->getPrefixInfo($new_name);
|
$info = $this->getPrefixInfo($new_name);
|
||||||
$this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $info['table']);
|
$this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $info['table']);
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
+10
-10
@@ -12,11 +12,6 @@ function system_default_date_formats() {
|
|||||||
$formats = array();
|
$formats = array();
|
||||||
|
|
||||||
// Short date formats.
|
// Short date formats.
|
||||||
$formats[] = array(
|
|
||||||
'type' => 'short',
|
|
||||||
'format' => 'Y-m-d H:i',
|
|
||||||
'locales' => array(),
|
|
||||||
);
|
|
||||||
$formats[] = array(
|
$formats[] = array(
|
||||||
'type' => 'short',
|
'type' => 'short',
|
||||||
'format' => 'm/d/Y - H:i',
|
'format' => 'm/d/Y - H:i',
|
||||||
@@ -37,6 +32,11 @@ function system_default_date_formats() {
|
|||||||
'format' => 'd.m.Y - H:i',
|
'format' => 'd.m.Y - H:i',
|
||||||
'locales' => array('de-ch', 'de-de', 'de-lu', 'fi-fi', 'fr-ch', 'is-is', 'pl-pl', 'ro-ro', 'ru-ru'),
|
'locales' => array('de-ch', 'de-de', 'de-lu', 'fi-fi', 'fr-ch', 'is-is', 'pl-pl', 'ro-ro', 'ru-ru'),
|
||||||
);
|
);
|
||||||
|
$formats[] = array(
|
||||||
|
'type' => 'short',
|
||||||
|
'format' => 'Y-m-d H:i',
|
||||||
|
'locales' => array(),
|
||||||
|
);
|
||||||
$formats[] = array(
|
$formats[] = array(
|
||||||
'type' => 'short',
|
'type' => 'short',
|
||||||
'format' => 'm/d/Y - g:ia',
|
'format' => 'm/d/Y - g:ia',
|
||||||
@@ -84,11 +84,6 @@ function system_default_date_formats() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Medium date formats.
|
// Medium date formats.
|
||||||
$formats[] = array(
|
|
||||||
'type' => 'medium',
|
|
||||||
'format' => 'D, Y-m-d H:i',
|
|
||||||
'locales' => array(),
|
|
||||||
);
|
|
||||||
$formats[] = array(
|
$formats[] = array(
|
||||||
'type' => 'medium',
|
'type' => 'medium',
|
||||||
'format' => 'D, m/d/Y - H:i',
|
'format' => 'D, m/d/Y - H:i',
|
||||||
@@ -104,6 +99,11 @@ function system_default_date_formats() {
|
|||||||
'format' => 'D, Y/m/d - H:i',
|
'format' => 'D, Y/m/d - H:i',
|
||||||
'locales' => array('en-ca', 'fr-ca', 'no-no', 'sv-se'),
|
'locales' => array('en-ca', 'fr-ca', 'no-no', 'sv-se'),
|
||||||
);
|
);
|
||||||
|
$formats[] = array(
|
||||||
|
'type' => 'medium',
|
||||||
|
'format' => 'D, Y-m-d H:i',
|
||||||
|
'locales' => array(),
|
||||||
|
);
|
||||||
$formats[] = array(
|
$formats[] = array(
|
||||||
'type' => 'medium',
|
'type' => 'medium',
|
||||||
'format' => 'F j, Y - H:i',
|
'format' => 'F j, Y - H:i',
|
||||||
|
|||||||
Executable → Regular
+3
-3
@@ -66,7 +66,7 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c
|
|||||||
_drupal_log_error(array(
|
_drupal_log_error(array(
|
||||||
'%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
|
'%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
|
||||||
// The standard PHP error handler considers that the error messages
|
// The standard PHP error handler considers that the error messages
|
||||||
// are HTML. We mimick this behavior here.
|
// are HTML. We mimic this behavior here.
|
||||||
'!message' => filter_xss_admin($message),
|
'!message' => filter_xss_admin($message),
|
||||||
'%function' => $caller['function'],
|
'%function' => $caller['function'],
|
||||||
'%file' => $caller['file'],
|
'%file' => $caller['file'],
|
||||||
@@ -114,7 +114,7 @@ function _drupal_decode_exception($exception) {
|
|||||||
return array(
|
return array(
|
||||||
'%type' => get_class($exception),
|
'%type' => get_class($exception),
|
||||||
// The standard PHP exception handler considers that the exception message
|
// The standard PHP exception handler considers that the exception message
|
||||||
// is plain-text. We mimick this behavior here.
|
// is plain-text. We mimic this behavior here.
|
||||||
'!message' => check_plain($message),
|
'!message' => check_plain($message),
|
||||||
'%function' => $caller['function'],
|
'%function' => $caller['function'],
|
||||||
'%file' => $caller['file'],
|
'%file' => $caller['file'],
|
||||||
@@ -233,7 +233,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Display the message if the current error reporting level allows this type
|
// Display the message if the current error reporting level allows this type
|
||||||
// of message to be displayed, and unconditionnaly in update.php.
|
// of message to be displayed, and unconditionally in update.php.
|
||||||
if (error_displayable($error)) {
|
if (error_displayable($error)) {
|
||||||
$class = 'error';
|
$class = 'error';
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+79
-8
@@ -532,10 +532,24 @@ SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
|
|||||||
<IfModule mod_php5.c>
|
<IfModule mod_php5.c>
|
||||||
php_flag engine off
|
php_flag engine off
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
<IfModule mod_php7.c>
|
||||||
|
php_flag engine off
|
||||||
|
</IfModule>
|
||||||
EOF;
|
EOF;
|
||||||
|
|
||||||
if ($private) {
|
if ($private) {
|
||||||
$lines = "Deny from all\n\n" . $lines;
|
$lines = <<<EOF
|
||||||
|
# Deny all requests from Apache 2.4+.
|
||||||
|
<IfModule mod_authz_core.c>
|
||||||
|
Require all denied
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# Deny all requests from Apache 2.0-2.2.
|
||||||
|
<IfModule !mod_authz_core.c>
|
||||||
|
Deny from all
|
||||||
|
</IfModule>
|
||||||
|
EOF
|
||||||
|
. "\n\n" . $lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $lines;
|
return $lines;
|
||||||
@@ -889,7 +903,6 @@ function file_valid_uri($uri) {
|
|||||||
*/
|
*/
|
||||||
function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
|
function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
|
||||||
$original_source = $source;
|
$original_source = $source;
|
||||||
$original_destination = $destination;
|
|
||||||
|
|
||||||
// Assert that the source file actually exists.
|
// Assert that the source file actually exists.
|
||||||
if (!file_exists($source)) {
|
if (!file_exists($source)) {
|
||||||
@@ -983,8 +996,15 @@ function file_build_uri($path) {
|
|||||||
* @return
|
* @return
|
||||||
* The destination filepath, or FALSE if the file already exists
|
* The destination filepath, or FALSE if the file already exists
|
||||||
* and FILE_EXISTS_ERROR is specified.
|
* and FILE_EXISTS_ERROR is specified.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException
|
||||||
|
* Thrown if the filename contains invalid UTF-8.
|
||||||
*/
|
*/
|
||||||
function file_destination($destination, $replace) {
|
function file_destination($destination, $replace) {
|
||||||
|
$basename = drupal_basename($destination);
|
||||||
|
if (!drupal_validate_utf8($basename)) {
|
||||||
|
throw new RuntimeException(sprintf("Invalid filename '%s'", $basename));
|
||||||
|
}
|
||||||
if (file_exists($destination)) {
|
if (file_exists($destination)) {
|
||||||
switch ($replace) {
|
switch ($replace) {
|
||||||
case FILE_EXISTS_REPLACE:
|
case FILE_EXISTS_REPLACE:
|
||||||
@@ -992,7 +1012,6 @@ function file_destination($destination, $replace) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FILE_EXISTS_RENAME:
|
case FILE_EXISTS_RENAME:
|
||||||
$basename = drupal_basename($destination);
|
|
||||||
$directory = drupal_dirname($destination);
|
$directory = drupal_dirname($destination);
|
||||||
$destination = file_create_filename($basename, $directory);
|
$destination = file_create_filename($basename, $directory);
|
||||||
break;
|
break;
|
||||||
@@ -1208,11 +1227,20 @@ function file_unmunge_filename($filename) {
|
|||||||
* @return
|
* @return
|
||||||
* File path consisting of $directory and a unique filename based off
|
* File path consisting of $directory and a unique filename based off
|
||||||
* of $basename.
|
* of $basename.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException
|
||||||
|
* Thrown if the $basename is not valid UTF-8 or another error occurs
|
||||||
|
* stripping control characters.
|
||||||
*/
|
*/
|
||||||
function file_create_filename($basename, $directory) {
|
function file_create_filename($basename, $directory) {
|
||||||
|
$original = $basename;
|
||||||
// Strip control characters (ASCII value < 32). Though these are allowed in
|
// Strip control characters (ASCII value < 32). Though these are allowed in
|
||||||
// some filesystems, not many applications handle them well.
|
// some filesystems, not many applications handle them well.
|
||||||
$basename = preg_replace('/[\x00-\x1F]/u', '_', $basename);
|
$basename = preg_replace('/[\x00-\x1F]/u', '_', $basename);
|
||||||
|
if (preg_last_error() !== PREG_NO_ERROR) {
|
||||||
|
throw new RuntimeException(sprintf("Invalid filename '%s'", $original));
|
||||||
|
}
|
||||||
|
|
||||||
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||||
// These characters are not allowed in Windows filenames
|
// These characters are not allowed in Windows filenames
|
||||||
$basename = str_replace(array(':', '*', '?', '"', '<', '>', '|'), '_', $basename);
|
$basename = str_replace(array(':', '*', '?', '"', '<', '>', '|'), '_', $basename);
|
||||||
@@ -1524,9 +1552,9 @@ function file_save_upload($form_field_name, $validators = array(), $destination
|
|||||||
// rename filename.php.foo and filename.php to filename.php.foo.txt and
|
// rename filename.php.foo and filename.php to filename.php.foo.txt and
|
||||||
// filename.php.txt, respectively). Don't rename if 'allow_insecure_uploads'
|
// filename.php.txt, respectively). Don't rename if 'allow_insecure_uploads'
|
||||||
// evaluates to TRUE.
|
// evaluates to TRUE.
|
||||||
if (!variable_get('allow_insecure_uploads', 0) && preg_match('/\.(php|pl|py|cgi|asp|js)(\.|$)/i', $file->filename) && (substr($file->filename, -4) != '.txt')) {
|
if (!variable_get('allow_insecure_uploads', 0) && preg_match('/\.(php|phar|pl|py|cgi|asp|js)(\.|$)/i', $file->filename) && (substr($file->filename, -4) != '.txt')) {
|
||||||
$file->filemime = 'text/plain';
|
$file->filemime = 'text/plain';
|
||||||
$file->uri .= '.txt';
|
// The destination filename will also later be used to create the URI.
|
||||||
$file->filename .= '.txt';
|
$file->filename .= '.txt';
|
||||||
// The .txt extension may not be in the allowed list of extensions. We have
|
// The .txt extension may not be in the allowed list of extensions. We have
|
||||||
// to add it here or else the file upload will fail.
|
// to add it here or else the file upload will fail.
|
||||||
@@ -1553,7 +1581,13 @@ function file_save_upload($form_field_name, $validators = array(), $destination
|
|||||||
if (substr($destination, -1) != '/') {
|
if (substr($destination, -1) != '/') {
|
||||||
$destination .= '/';
|
$destination .= '/';
|
||||||
}
|
}
|
||||||
$file->destination = file_destination($destination . $file->filename, $replace);
|
try {
|
||||||
|
$file->destination = file_destination($destination . $file->filename, $replace);
|
||||||
|
}
|
||||||
|
catch (RuntimeException $e) {
|
||||||
|
drupal_set_message(t('The file %source could not be uploaded because the name is invalid.', array('%source' => $form_field_name)), 'error');
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
// If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
|
// If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
|
||||||
// there's an existing file so we need to bail.
|
// there's an existing file so we need to bail.
|
||||||
if ($file->destination === FALSE) {
|
if ($file->destination === FALSE) {
|
||||||
@@ -1604,6 +1638,20 @@ function file_save_upload($form_field_name, $validators = array(), $destination
|
|||||||
|
|
||||||
// If we made it this far it's safe to record this file in the database.
|
// If we made it this far it's safe to record this file in the database.
|
||||||
if ($file = file_save($file)) {
|
if ($file = file_save($file)) {
|
||||||
|
// Track non-public files in the session if they were uploaded by an
|
||||||
|
// anonymous user. This allows modules such as the File module to only
|
||||||
|
// grant view access to the specific anonymous user who uploaded the file.
|
||||||
|
// See file_file_download().
|
||||||
|
// The 'file_public_schema' variable is used to allow other publicly
|
||||||
|
// accessible file schemes to be treated the same as the public:// scheme
|
||||||
|
// provided by Drupal core and to avoid adding unnecessary data to the
|
||||||
|
// session (and the resulting bypass of the page cache) in those cases. For
|
||||||
|
// security reasons, only schemes that are completely publicly accessible,
|
||||||
|
// with no download restrictions, should be added to this variable. See
|
||||||
|
// file_managed_file_value().
|
||||||
|
if (!$user->uid && !in_array($destination_scheme, variable_get('file_public_schema', array('public')))) {
|
||||||
|
$_SESSION['anonymous_allowed_file_ids'][$file->fid] = $file->fid;
|
||||||
|
}
|
||||||
// Add file to the cache.
|
// Add file to the cache.
|
||||||
$upload_cache[$form_field_name] = $file;
|
$upload_cache[$form_field_name] = $file;
|
||||||
return $file;
|
return $file;
|
||||||
@@ -2106,9 +2154,33 @@ function file_download_access($uri) {
|
|||||||
* 'filename', and 'name' members corresponding to the matching files.
|
* 'filename', and 'name' members corresponding to the matching files.
|
||||||
*/
|
*/
|
||||||
function file_scan_directory($dir, $mask, $options = array(), $depth = 0) {
|
function file_scan_directory($dir, $mask, $options = array(), $depth = 0) {
|
||||||
|
// Default nomask option.
|
||||||
|
$nomask = '/(\.\.?|CVS)$/';
|
||||||
|
|
||||||
|
// Overrides the $nomask variable accordingly if $options['nomask'] is set.
|
||||||
|
//
|
||||||
|
// Allow directories specified in settings.php to be ignored. You can use this
|
||||||
|
// to not check for files in common special-purpose directories. For example,
|
||||||
|
// node_modules and bower_components. Ignoring irrelevant directories is a
|
||||||
|
// performance boost.
|
||||||
|
if (!isset($options['nomask'])) {
|
||||||
|
$ignore_directories = variable_get(
|
||||||
|
'file_scan_ignore_directories',
|
||||||
|
array()
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($ignore_directories as $index => $ignore_directory) {
|
||||||
|
$ignore_directories[$index] = preg_quote($ignore_directory, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($ignore_directories)) {
|
||||||
|
$nomask = '/^(\.\.?)|CVS|' . implode('|', $ignore_directories) . '$/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Merge in defaults.
|
// Merge in defaults.
|
||||||
$options += array(
|
$options += array(
|
||||||
'nomask' => '/(\.\.?|CVS)$/',
|
'nomask' => $nomask,
|
||||||
'callback' => 0,
|
'callback' => 0,
|
||||||
'recurse' => TRUE,
|
'recurse' => TRUE,
|
||||||
'key' => 'uri',
|
'key' => 'uri',
|
||||||
@@ -2553,7 +2625,6 @@ function file_directory_temp() {
|
|||||||
* An associative array of headers, as expected by file_transfer().
|
* An associative array of headers, as expected by file_transfer().
|
||||||
*/
|
*/
|
||||||
function file_get_content_headers($file) {
|
function file_get_content_headers($file) {
|
||||||
$name = mime_header_encode($file->filename);
|
|
||||||
$type = mime_header_encode($file->filemime);
|
$type = mime_header_encode($file->filemime);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|||||||
Executable → Regular
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Drupal\Core\Security\PharExtensionInterceptor;
|
||||||
|
use TYPO3\PharStreamWrapper\Manager as PharStreamWrapperManager;
|
||||||
|
use TYPO3\PharStreamWrapper\Behavior as PharStreamWrapperBehavior;
|
||||||
|
use TYPO3\PharStreamWrapper\PharStreamWrapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a phar stream wrapper that is more secure than PHP's built-in one.
|
||||||
|
*
|
||||||
|
* @see file_get_stream_wrappers()
|
||||||
|
*/
|
||||||
|
function file_register_phar_wrapper() {
|
||||||
|
$directory = DRUPAL_ROOT . '/misc/typo3/phar-stream-wrapper/src';
|
||||||
|
include_once $directory . '/Assertable.php';
|
||||||
|
include_once $directory . '/Behavior.php';
|
||||||
|
include_once $directory . '/Exception.php';
|
||||||
|
include_once $directory . '/Helper.php';
|
||||||
|
include_once $directory . '/Manager.php';
|
||||||
|
include_once $directory . '/PharStreamWrapper.php';
|
||||||
|
include_once $directory . '/Collectable.php';
|
||||||
|
include_once $directory . '/Interceptor/ConjunctionInterceptor.php';
|
||||||
|
include_once $directory . '/Interceptor/PharMetaDataInterceptor.php';
|
||||||
|
include_once $directory . '/Phar/Container.php';
|
||||||
|
include_once $directory . '/Phar/DeserializationException.php';
|
||||||
|
include_once $directory . '/Phar/Manifest.php';
|
||||||
|
include_once $directory . '/Phar/Reader.php';
|
||||||
|
include_once $directory . '/Phar/ReaderException.php';
|
||||||
|
include_once $directory . '/Phar/Stub.php';
|
||||||
|
include_once $directory . '/Resolvable.php';
|
||||||
|
include_once $directory . '/Resolver/PharInvocation.php';
|
||||||
|
include_once $directory . '/Resolver/PharInvocationCollection.php';
|
||||||
|
include_once $directory . '/Resolver/PharInvocationResolver.php';
|
||||||
|
include_once DRUPAL_ROOT . '/misc/typo3/drupal-security/PharExtensionInterceptor.php';
|
||||||
|
include_once DRUPAL_ROOT . '/misc/brumann/polyfill-unserialize/src/Unserialize.php';
|
||||||
|
|
||||||
|
// Set up a stream wrapper to handle insecurities due to PHP's built-in
|
||||||
|
// phar stream wrapper.
|
||||||
|
try {
|
||||||
|
$behavior = new PharStreamWrapperBehavior();
|
||||||
|
PharStreamWrapperManager::initialize(
|
||||||
|
$behavior->withAssertion(new PharExtensionInterceptor())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (\LogicException $e) {
|
||||||
|
// Continue if the PharStreamWrapperManager is already initialized.
|
||||||
|
// For example, this occurs following a drupal_static_reset(), such
|
||||||
|
// as during tests.
|
||||||
|
};
|
||||||
|
|
||||||
|
// To prevent file_stream_wrapper_valid_scheme() treating "phar" as a valid
|
||||||
|
// scheme, this is registered with PHP only, not with hook_stream_wrappers()
|
||||||
|
// or the internal storage of file_get_stream_wrappers().
|
||||||
|
stream_wrapper_register('phar', '\\TYPO3\\PharStreamWrapper\\PharStreamWrapper');
|
||||||
|
}
|
||||||
Executable → Regular
+1
-1
@@ -301,7 +301,7 @@ abstract class FileTransfer {
|
|||||||
$parts = explode('/', $path);
|
$parts = explode('/', $path);
|
||||||
$chroot = '';
|
$chroot = '';
|
||||||
while (count($parts)) {
|
while (count($parts)) {
|
||||||
$check = implode($parts, '/');
|
$check = implode('/', $parts);
|
||||||
if ($this->isFile($check . '/' . drupal_basename(__FILE__))) {
|
if ($this->isFile($check . '/' . drupal_basename(__FILE__))) {
|
||||||
// Remove the trailing slash.
|
// Remove the trailing slash.
|
||||||
return substr($chroot, 0, -1);
|
return substr($chroot, 0, -1);
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
+19
-11
@@ -555,8 +555,10 @@ function form_get_cache($form_build_id, &$form_state) {
|
|||||||
* Stores a form in the cache.
|
* Stores a form in the cache.
|
||||||
*/
|
*/
|
||||||
function form_set_cache($form_build_id, $form, $form_state) {
|
function form_set_cache($form_build_id, $form, $form_state) {
|
||||||
// 6 hours cache life time for forms should be plenty.
|
// The default cache_form expiration is 6 hours. On busy sites, the cache_form
|
||||||
$expire = 21600;
|
// table can become very large. A shorter cache lifetime can help to keep the
|
||||||
|
// table's size under control.
|
||||||
|
$expire = variable_get('form_cache_expiration', 21600);
|
||||||
|
|
||||||
// Ensure that the form build_id embedded in the form structure is the same as
|
// Ensure that the form build_id embedded in the form structure is the same as
|
||||||
// the one passed in as a parameter. This is an additional safety measure to
|
// the one passed in as a parameter. This is an additional safety measure to
|
||||||
@@ -1133,12 +1135,8 @@ function drupal_prepare_form($form_id, &$form, &$form_state) {
|
|||||||
* Helper function to call form_set_error() if there is a token error.
|
* Helper function to call form_set_error() if there is a token error.
|
||||||
*/
|
*/
|
||||||
function _drupal_invalid_token_set_form_error() {
|
function _drupal_invalid_token_set_form_error() {
|
||||||
$path = current_path();
|
|
||||||
$query = drupal_get_query_parameters();
|
|
||||||
$url = url($path, array('query' => $query));
|
|
||||||
|
|
||||||
// Setting this error will cause the form to fail validation.
|
// Setting this error will cause the form to fail validation.
|
||||||
form_set_error('form_token', t('The form has become outdated. Copy any unsaved work in the form below and then <a href="@link">reload this page</a>.', array('@link' => $url)));
|
form_set_error('form_token', t('The form has become outdated. Press the back button, copy any unsaved work in the form, and then reload the page.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1176,9 +1174,14 @@ function drupal_validate_form($form_id, &$form, &$form_state) {
|
|||||||
// If the session token was set by drupal_prepare_form(), ensure that it
|
// If the session token was set by drupal_prepare_form(), ensure that it
|
||||||
// matches the current user's session. This is duplicate to code in
|
// matches the current user's session. This is duplicate to code in
|
||||||
// form_builder() but left to protect any custom form handling code.
|
// form_builder() but left to protect any custom form handling code.
|
||||||
if (isset($form['#token'])) {
|
if (!empty($form['#token'])) {
|
||||||
if (!drupal_valid_token($form_state['values']['form_token'], $form['#token']) || !empty($form_state['invalid_token'])) {
|
if (!drupal_valid_token($form_state['values']['form_token'], $form['#token']) || !empty($form_state['invalid_token'])) {
|
||||||
_drupal_invalid_token_set_form_error();
|
_drupal_invalid_token_set_form_error();
|
||||||
|
// Ignore all submitted values.
|
||||||
|
$form_state['input'] = array();
|
||||||
|
$_POST = array();
|
||||||
|
// Make sure file uploads do not get processed.
|
||||||
|
$_FILES = array();
|
||||||
// Stop here and don't run any further validation handlers, because they
|
// Stop here and don't run any further validation handlers, because they
|
||||||
// could invoke non-safe operations which opens the door for CSRF
|
// could invoke non-safe operations which opens the door for CSRF
|
||||||
// vulnerabilities.
|
// vulnerabilities.
|
||||||
@@ -1438,10 +1441,12 @@ function _form_validate(&$elements, &$form_state, $form_id = NULL) {
|
|||||||
// length if it's a string, and the item count if it's an array.
|
// length if it's a string, and the item count if it's an array.
|
||||||
// An unchecked checkbox has a #value of integer 0, different than string
|
// An unchecked checkbox has a #value of integer 0, different than string
|
||||||
// '0', which could be a valid value.
|
// '0', which could be a valid value.
|
||||||
$is_empty_multiple = (!count($elements['#value']));
|
$is_countable = is_array($elements['#value']) || $elements['#value'] instanceof Countable;
|
||||||
|
$is_empty_multiple = $is_countable && count($elements['#value']) == 0;
|
||||||
$is_empty_string = (is_string($elements['#value']) && drupal_strlen(trim($elements['#value'])) == 0);
|
$is_empty_string = (is_string($elements['#value']) && drupal_strlen(trim($elements['#value'])) == 0);
|
||||||
$is_empty_value = ($elements['#value'] === 0);
|
$is_empty_value = ($elements['#value'] === 0);
|
||||||
if ($is_empty_multiple || $is_empty_string || $is_empty_value) {
|
$is_empty_null = is_null($elements['#value']);
|
||||||
|
if ($is_empty_multiple || $is_empty_string || $is_empty_value || $is_empty_null) {
|
||||||
// Although discouraged, a #title is not mandatory for form elements. In
|
// Although discouraged, a #title is not mandatory for form elements. In
|
||||||
// case there is no #title, we cannot set a form error message.
|
// case there is no #title, we cannot set a form error message.
|
||||||
// Instead of setting no #title, form constructors are encouraged to set
|
// Instead of setting no #title, form constructors are encouraged to set
|
||||||
@@ -1837,13 +1842,16 @@ function form_builder($form_id, &$element, &$form_state) {
|
|||||||
// If the session token was set by drupal_prepare_form(), ensure that it
|
// If the session token was set by drupal_prepare_form(), ensure that it
|
||||||
// matches the current user's session.
|
// matches the current user's session.
|
||||||
$form_state['invalid_token'] = FALSE;
|
$form_state['invalid_token'] = FALSE;
|
||||||
if (isset($element['#token'])) {
|
if (!empty($element['#token'])) {
|
||||||
if (empty($form_state['input']['form_token']) || !drupal_valid_token($form_state['input']['form_token'], $element['#token'])) {
|
if (empty($form_state['input']['form_token']) || !drupal_valid_token($form_state['input']['form_token'], $element['#token'])) {
|
||||||
// Set an early form error to block certain input processing since that
|
// Set an early form error to block certain input processing since that
|
||||||
// opens the door for CSRF vulnerabilities.
|
// opens the door for CSRF vulnerabilities.
|
||||||
_drupal_invalid_token_set_form_error();
|
_drupal_invalid_token_set_form_error();
|
||||||
// This value is checked in _form_builder_handle_input_element().
|
// This value is checked in _form_builder_handle_input_element().
|
||||||
$form_state['invalid_token'] = TRUE;
|
$form_state['invalid_token'] = TRUE;
|
||||||
|
// Ignore all submitted values.
|
||||||
|
$form_state['input'] = array();
|
||||||
|
$_POST = array();
|
||||||
// Make sure file uploads do not get processed.
|
// Make sure file uploads do not get processed.
|
||||||
$_FILES = array();
|
$_FILES = array();
|
||||||
}
|
}
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
+1
-1
@@ -779,7 +779,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents
|
|||||||
$module_list = array_flip(array_values($module_list));
|
$module_list = array_flip(array_values($module_list));
|
||||||
|
|
||||||
$profile = drupal_get_profile();
|
$profile = drupal_get_profile();
|
||||||
while (list($module) = each($module_list)) {
|
foreach (array_keys($module_list) as $module) {
|
||||||
if (!isset($module_data[$module]) || drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED) {
|
if (!isset($module_data[$module]) || drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED) {
|
||||||
// This module doesn't exist or is already uninstalled. Skip it.
|
// This module doesn't exist or is already uninstalled. Skip it.
|
||||||
unset($module_list[$module]);
|
unset($module_list[$module]);
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
+11
-4
@@ -576,7 +576,8 @@ function _menu_load_objects(&$item, &$map) {
|
|||||||
// 'load arguments' in the hook_menu() entry, but they need
|
// 'load arguments' in the hook_menu() entry, but they need
|
||||||
// some processing. In this case the $function is the key to the
|
// some processing. In this case the $function is the key to the
|
||||||
// load_function array, and the value is the list of arguments.
|
// load_function array, and the value is the list of arguments.
|
||||||
list($function, $args) = each($function);
|
$args = current($function);
|
||||||
|
$function = key($function);
|
||||||
$load_functions[$index] = $function;
|
$load_functions[$index] = $function;
|
||||||
|
|
||||||
// Some arguments are placeholders for dynamic items to process.
|
// Some arguments are placeholders for dynamic items to process.
|
||||||
@@ -1606,6 +1607,7 @@ function _menu_tree_data(&$links, $parents, $depth) {
|
|||||||
* Implements template_preprocess_HOOK() for theme_menu_tree().
|
* Implements template_preprocess_HOOK() for theme_menu_tree().
|
||||||
*/
|
*/
|
||||||
function template_preprocess_menu_tree(&$variables) {
|
function template_preprocess_menu_tree(&$variables) {
|
||||||
|
$variables['#tree'] = $variables['tree'];
|
||||||
$variables['tree'] = $variables['tree']['#children'];
|
$variables['tree'] = $variables['tree']['#children'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2401,7 +2403,8 @@ function menu_set_active_trail($new_trail = NULL) {
|
|||||||
// a stripped down menu tree containing the active trail only, in case
|
// a stripped down menu tree containing the active trail only, in case
|
||||||
// the given menu has not been built in this request yet.
|
// the given menu has not been built in this request yet.
|
||||||
$tree = menu_tree_page_data($preferred_link['menu_name'], NULL, TRUE);
|
$tree = menu_tree_page_data($preferred_link['menu_name'], NULL, TRUE);
|
||||||
list($key, $curr) = each($tree);
|
$curr = current($tree);
|
||||||
|
next($tree);
|
||||||
}
|
}
|
||||||
// There is no link for the current path.
|
// There is no link for the current path.
|
||||||
else {
|
else {
|
||||||
@@ -2431,7 +2434,8 @@ function menu_set_active_trail($new_trail = NULL) {
|
|||||||
}
|
}
|
||||||
$tree = $curr['below'] ? $curr['below'] : array();
|
$tree = $curr['below'] ? $curr['below'] : array();
|
||||||
}
|
}
|
||||||
list($key, $curr) = each($tree);
|
$curr = current($tree);
|
||||||
|
next($tree);
|
||||||
}
|
}
|
||||||
// Make sure the current page is in the trail to build the page title, by
|
// Make sure the current page is in the trail to build the page title, by
|
||||||
// appending either the preferred link or the menu router item for the
|
// appending either the preferred link or the menu router item for the
|
||||||
@@ -2479,6 +2483,9 @@ function menu_link_get_preferred($path = NULL, $selected_menu = NULL) {
|
|||||||
// untranslated paths). Afterwards, the most relevant path is picked from
|
// untranslated paths). Afterwards, the most relevant path is picked from
|
||||||
// the menus, ordered by menu preference.
|
// the menus, ordered by menu preference.
|
||||||
$item = menu_get_item($path);
|
$item = menu_get_item($path);
|
||||||
|
if ($item === FALSE) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
$path_candidates = array();
|
$path_candidates = array();
|
||||||
// 1. The current item href.
|
// 1. The current item href.
|
||||||
$path_candidates[$item['href']] = $item['href'];
|
$path_candidates[$item['href']] = $item['href'];
|
||||||
@@ -2682,7 +2689,7 @@ function menu_link_load($mlid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the cached cached data for a single named menu.
|
* Clears the cached data for a single named menu.
|
||||||
*/
|
*/
|
||||||
function menu_cache_clear($menu_name = 'navigation') {
|
function menu_cache_clear($menu_name = 'navigation') {
|
||||||
$cache_cleared = &drupal_static(__FUNCTION__, array());
|
$cache_cleared = &drupal_static(__FUNCTION__, array());
|
||||||
|
|||||||
Executable → Regular
+10
-2
@@ -404,7 +404,11 @@ function module_enable($module_list, $enable_dependencies = TRUE) {
|
|||||||
// Create an associative array with weights as values.
|
// Create an associative array with weights as values.
|
||||||
$module_list = array_flip(array_values($module_list));
|
$module_list = array_flip(array_values($module_list));
|
||||||
|
|
||||||
while (list($module) = each($module_list)) {
|
// The array is iterated over manually (instead of using a foreach) because
|
||||||
|
// modules may be added to the list within the loop and we need to process
|
||||||
|
// them.
|
||||||
|
while ($module = key($module_list)) {
|
||||||
|
next($module_list);
|
||||||
if (!isset($module_data[$module])) {
|
if (!isset($module_data[$module])) {
|
||||||
// This module is not found in the filesystem, abort.
|
// This module is not found in the filesystem, abort.
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -540,7 +544,11 @@ function module_disable($module_list, $disable_dependents = TRUE) {
|
|||||||
$module_list = array_flip(array_values($module_list));
|
$module_list = array_flip(array_values($module_list));
|
||||||
|
|
||||||
$profile = drupal_get_profile();
|
$profile = drupal_get_profile();
|
||||||
while (list($module) = each($module_list)) {
|
// The array is iterated over manually (instead of using a foreach) because
|
||||||
|
// modules may be added to the list within the loop and we need to process
|
||||||
|
// them.
|
||||||
|
while ($module = key($module_list)) {
|
||||||
|
next($module_list);
|
||||||
if (!isset($module_data[$module]) || !$module_data[$module]->status) {
|
if (!isset($module_data[$module]) || !$module_data[$module]->status) {
|
||||||
// This module doesn't exist or is already disabled, skip it.
|
// This module doesn't exist or is already disabled, skip it.
|
||||||
unset($module_list[$module]);
|
unset($module_list[$module]);
|
||||||
|
|||||||
Executable → Regular
+31
-1
@@ -321,9 +321,19 @@ function theme_pager($variables) {
|
|||||||
$tags = $variables['tags'];
|
$tags = $variables['tags'];
|
||||||
$element = $variables['element'];
|
$element = $variables['element'];
|
||||||
$parameters = $variables['parameters'];
|
$parameters = $variables['parameters'];
|
||||||
$quantity = $variables['quantity'];
|
$quantity = empty($variables['quantity']) ? 0 : $variables['quantity'];
|
||||||
global $pager_page_array, $pager_total;
|
global $pager_page_array, $pager_total;
|
||||||
|
|
||||||
|
// Nothing to do if there is no pager.
|
||||||
|
if (!isset($pager_page_array[$element]) || !isset($pager_total[$element])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing to do if there is only one page.
|
||||||
|
if ($pager_total[$element] <= 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate various markers within this pager piece:
|
// Calculate various markers within this pager piece:
|
||||||
// Middle is used to "center" pages around the current page.
|
// Middle is used to "center" pages around the current page.
|
||||||
$pager_middle = ceil($quantity / 2);
|
$pager_middle = ceil($quantity / 2);
|
||||||
@@ -455,6 +465,11 @@ function theme_pager_first($variables) {
|
|||||||
global $pager_page_array;
|
global $pager_page_array;
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
|
// Nothing to do if there is no pager.
|
||||||
|
if (!isset($pager_page_array[$element])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If we are anywhere but the first page
|
// If we are anywhere but the first page
|
||||||
if ($pager_page_array[$element] > 0) {
|
if ($pager_page_array[$element] > 0) {
|
||||||
$output = theme('pager_link', array('text' => $text, 'page_new' => pager_load_array(0, $element, $pager_page_array), 'element' => $element, 'parameters' => $parameters));
|
$output = theme('pager_link', array('text' => $text, 'page_new' => pager_load_array(0, $element, $pager_page_array), 'element' => $element, 'parameters' => $parameters));
|
||||||
@@ -485,6 +500,11 @@ function theme_pager_previous($variables) {
|
|||||||
global $pager_page_array;
|
global $pager_page_array;
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
|
// Nothing to do if there is no pager.
|
||||||
|
if (!isset($pager_page_array[$element])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If we are anywhere but the first page
|
// If we are anywhere but the first page
|
||||||
if ($pager_page_array[$element] > 0) {
|
if ($pager_page_array[$element] > 0) {
|
||||||
$page_new = pager_load_array($pager_page_array[$element] - $interval, $element, $pager_page_array);
|
$page_new = pager_load_array($pager_page_array[$element] - $interval, $element, $pager_page_array);
|
||||||
@@ -524,6 +544,11 @@ function theme_pager_next($variables) {
|
|||||||
global $pager_page_array, $pager_total;
|
global $pager_page_array, $pager_total;
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
|
// Nothing to do if there is no pager.
|
||||||
|
if (!isset($pager_page_array[$element]) || !isset($pager_total[$element])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If we are anywhere but the last page
|
// If we are anywhere but the last page
|
||||||
if ($pager_page_array[$element] < ($pager_total[$element] - 1)) {
|
if ($pager_page_array[$element] < ($pager_total[$element] - 1)) {
|
||||||
$page_new = pager_load_array($pager_page_array[$element] + $interval, $element, $pager_page_array);
|
$page_new = pager_load_array($pager_page_array[$element] + $interval, $element, $pager_page_array);
|
||||||
@@ -560,6 +585,11 @@ function theme_pager_last($variables) {
|
|||||||
global $pager_page_array, $pager_total;
|
global $pager_page_array, $pager_total;
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
|
// Nothing to do if there is no pager.
|
||||||
|
if (!isset($pager_page_array[$element]) || !isset($pager_total[$element])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If we are anywhere but the last page
|
// If we are anywhere but the last page
|
||||||
if ($pager_page_array[$element] < ($pager_total[$element] - 1)) {
|
if ($pager_page_array[$element] < ($pager_total[$element] - 1)) {
|
||||||
$output = theme('pager_link', array('text' => $text, 'page_new' => pager_load_array($pager_total[$element] - 1, $element, $pager_page_array), 'element' => $element, 'parameters' => $parameters));
|
$output = theme('pager_link', array('text' => $text, 'page_new' => pager_load_array($pager_total[$element] - 1, $element, $pager_page_array), 'element' => $element, 'parameters' => $parameters));
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
+8
-6
@@ -466,13 +466,15 @@ function path_delete($criteria) {
|
|||||||
$criteria = array('pid' => $criteria);
|
$criteria = array('pid' => $criteria);
|
||||||
}
|
}
|
||||||
$path = path_load($criteria);
|
$path = path_load($criteria);
|
||||||
$query = db_delete('url_alias');
|
if (isset($path['source'])) {
|
||||||
foreach ($criteria as $field => $value) {
|
$query = db_delete('url_alias');
|
||||||
$query->condition($field, $value);
|
foreach ($criteria as $field => $value) {
|
||||||
|
$query->condition($field, $value);
|
||||||
|
}
|
||||||
|
$query->execute();
|
||||||
|
module_invoke_all('path_delete', $path);
|
||||||
|
drupal_clear_path_cache($path['source']);
|
||||||
}
|
}
|
||||||
$query->execute();
|
|
||||||
module_invoke_all('path_delete', $path);
|
|
||||||
drupal_clear_path_cache($path['source']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Executable → Regular
+30
-5
@@ -19,7 +19,6 @@
|
|||||||
* Does the work for registry_update().
|
* Does the work for registry_update().
|
||||||
*/
|
*/
|
||||||
function _registry_update() {
|
function _registry_update() {
|
||||||
|
|
||||||
// The registry serves as a central autoloader for all classes, including
|
// The registry serves as a central autoloader for all classes, including
|
||||||
// the database query builders. However, the registry rebuild process
|
// the database query builders. However, the registry rebuild process
|
||||||
// requires write ability to the database, which means having access to the
|
// requires write ability to the database, which means having access to the
|
||||||
@@ -33,6 +32,11 @@ function _registry_update() {
|
|||||||
require_once DRUPAL_ROOT . '/includes/database/select.inc';
|
require_once DRUPAL_ROOT . '/includes/database/select.inc';
|
||||||
require_once DRUPAL_ROOT . '/includes/database/' . $driver . '/query.inc';
|
require_once DRUPAL_ROOT . '/includes/database/' . $driver . '/query.inc';
|
||||||
|
|
||||||
|
// During the first registry rebuild in a request, we check all the files.
|
||||||
|
// During subsequent rebuilds, we only add new files. It makes the rebuilding
|
||||||
|
// process faster during installation of modules.
|
||||||
|
static $check_existing_files = TRUE;
|
||||||
|
|
||||||
// Get current list of modules and their files.
|
// Get current list of modules and their files.
|
||||||
$modules = db_query("SELECT * FROM {system} WHERE type = 'module'")->fetchAll();
|
$modules = db_query("SELECT * FROM {system} WHERE type = 'module'")->fetchAll();
|
||||||
// Get the list of files we are going to parse.
|
// Get the list of files we are going to parse.
|
||||||
@@ -55,6 +59,9 @@ function _registry_update() {
|
|||||||
$files["$filename"] = array('module' => '', 'weight' => 0);
|
$files["$filename"] = array('module' => '', 'weight' => 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize an empty array for the unchanged files.
|
||||||
|
$unchanged_files = array();
|
||||||
|
|
||||||
$transaction = db_transaction();
|
$transaction = db_transaction();
|
||||||
try {
|
try {
|
||||||
// Allow modules to manually modify the list of files before the registry
|
// Allow modules to manually modify the list of files before the registry
|
||||||
@@ -63,10 +70,19 @@ function _registry_update() {
|
|||||||
// list can then be added to the list of files that the registry will parse,
|
// list can then be added to the list of files that the registry will parse,
|
||||||
// or modify attributes of a file.
|
// or modify attributes of a file.
|
||||||
drupal_alter('registry_files', $files, $modules);
|
drupal_alter('registry_files', $files, $modules);
|
||||||
|
|
||||||
foreach (registry_get_parsed_files() as $filename => $file) {
|
foreach (registry_get_parsed_files() as $filename => $file) {
|
||||||
// Add the hash for those files we have already parsed.
|
// Add the hash for those files we have already parsed.
|
||||||
if (isset($files[$filename])) {
|
if (isset($files[$filename])) {
|
||||||
$files[$filename]['hash'] = $file['hash'];
|
if ($check_existing_files === TRUE) {
|
||||||
|
$files[$filename]['hash'] = $file['hash'];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Ignore that file for this request, it has been parsed previously
|
||||||
|
// and it is unlikely it has changed.
|
||||||
|
unset($files[$filename]);
|
||||||
|
$unchanged_files[$filename] = $file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Flush the registry of resources in files that are no longer on disc
|
// Flush the registry of resources in files that are no longer on disc
|
||||||
@@ -79,8 +95,12 @@ function _registry_update() {
|
|||||||
->execute();
|
->execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$parsed_files = _registry_parse_files($files);
|
$parsed_files = _registry_parse_files($files);
|
||||||
|
|
||||||
|
// Add unchanged files to the files.
|
||||||
|
$files += $unchanged_files;
|
||||||
|
|
||||||
$unchanged_resources = array();
|
$unchanged_resources = array();
|
||||||
$lookup_cache = array();
|
$lookup_cache = array();
|
||||||
if ($cache = cache_get('lookup_cache', 'cache_bootstrap')) {
|
if ($cache = cache_get('lookup_cache', 'cache_bootstrap')) {
|
||||||
@@ -89,12 +109,10 @@ function _registry_update() {
|
|||||||
foreach ($lookup_cache as $key => $file) {
|
foreach ($lookup_cache as $key => $file) {
|
||||||
// If the file for this cached resource is carried over unchanged from
|
// If the file for this cached resource is carried over unchanged from
|
||||||
// the last registry build, then we can safely re-cache it.
|
// the last registry build, then we can safely re-cache it.
|
||||||
if ($file && in_array($file, array_keys($files)) && !in_array($file, $parsed_files)) {
|
if ($file && isset($files[$file]) && !in_array($file, $parsed_files, TRUE)) {
|
||||||
$unchanged_resources[$key] = $file;
|
$unchanged_resources[$key] = $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module_implements('', FALSE, TRUE);
|
|
||||||
_registry_check_code(REGISTRY_RESET_LOOKUP_CACHE);
|
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
$transaction->rollback();
|
$transaction->rollback();
|
||||||
@@ -102,6 +120,13 @@ function _registry_update() {
|
|||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module_implements('', FALSE, TRUE);
|
||||||
|
_registry_check_code(REGISTRY_RESET_LOOKUP_CACHE);
|
||||||
|
|
||||||
|
// During the next run in this request, don't bother re-checking existing
|
||||||
|
// files.
|
||||||
|
$check_existing_files = FALSE;
|
||||||
|
|
||||||
// We have some unchanged resources, warm up the cache - no need to pay
|
// We have some unchanged resources, warm up the cache - no need to pay
|
||||||
// for looking them up again.
|
// for looking them up again.
|
||||||
if (count($unchanged_resources) > 0) {
|
if (count($unchanged_resources) > 0) {
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains code for sanitizing user input from the request.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitizes user input from the request.
|
||||||
|
*/
|
||||||
|
class DrupalRequestSanitizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks whether the request was already sanitized.
|
||||||
|
*/
|
||||||
|
protected static $sanitized = FALSE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies the request to strip dangerous keys from user input.
|
||||||
|
*/
|
||||||
|
public static function sanitize() {
|
||||||
|
if (!self::$sanitized) {
|
||||||
|
$whitelist = variable_get('sanitize_input_whitelist', array());
|
||||||
|
$log_sanitized_keys = variable_get('sanitize_input_logging', FALSE);
|
||||||
|
|
||||||
|
// Process query string parameters.
|
||||||
|
$get_sanitized_keys = array();
|
||||||
|
$_GET = self::stripDangerousValues($_GET, $whitelist, $get_sanitized_keys);
|
||||||
|
if ($log_sanitized_keys && $get_sanitized_keys) {
|
||||||
|
_drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from query string parameters (GET): @keys', array('@keys' => implode(', ', $get_sanitized_keys))), E_USER_NOTICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process request body parameters.
|
||||||
|
$post_sanitized_keys = array();
|
||||||
|
$_POST = self::stripDangerousValues($_POST, $whitelist, $post_sanitized_keys);
|
||||||
|
if ($log_sanitized_keys && $post_sanitized_keys) {
|
||||||
|
_drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from request body parameters (POST): @keys', array('@keys' => implode(', ', $post_sanitized_keys))), E_USER_NOTICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process cookie parameters.
|
||||||
|
$cookie_sanitized_keys = array();
|
||||||
|
$_COOKIE = self::stripDangerousValues($_COOKIE, $whitelist, $cookie_sanitized_keys);
|
||||||
|
if ($log_sanitized_keys && $cookie_sanitized_keys) {
|
||||||
|
_drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from cookie parameters (COOKIE): @keys', array('@keys' => implode(', ', $cookie_sanitized_keys))), E_USER_NOTICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
$request_sanitized_keys = array();
|
||||||
|
$_REQUEST = self::stripDangerousValues($_REQUEST, $whitelist, $request_sanitized_keys);
|
||||||
|
|
||||||
|
self::$sanitized = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the destination if it is dangerous.
|
||||||
|
*
|
||||||
|
* Note this can only be called after common.inc has been included.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* TRUE if the destination has been removed from $_GET, FALSE if not.
|
||||||
|
*/
|
||||||
|
public static function cleanDestination() {
|
||||||
|
$dangerous_keys = array();
|
||||||
|
$log_sanitized_keys = variable_get('sanitize_input_logging', FALSE);
|
||||||
|
|
||||||
|
$parts = drupal_parse_url($_GET['destination']);
|
||||||
|
// If there is a query string, check its query parameters.
|
||||||
|
if (!empty($parts['query'])) {
|
||||||
|
$whitelist = variable_get('sanitize_input_whitelist', array());
|
||||||
|
|
||||||
|
self::stripDangerousValues($parts['query'], $whitelist, $dangerous_keys);
|
||||||
|
if (!empty($dangerous_keys)) {
|
||||||
|
// The destination is removed rather than sanitized to mirror the
|
||||||
|
// handling of external destinations.
|
||||||
|
unset($_GET['destination']);
|
||||||
|
unset($_REQUEST['destination']);
|
||||||
|
if ($log_sanitized_keys) {
|
||||||
|
trigger_error(format_string('Potentially unsafe destination removed from query string parameters (GET) because it contained the following keys: @keys', array('@keys' => implode(', ', $dangerous_keys))));
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strips dangerous keys from the provided input.
|
||||||
|
*
|
||||||
|
* @param mixed $input
|
||||||
|
* The input to sanitize.
|
||||||
|
* @param string[] $whitelist
|
||||||
|
* An array of keys to whitelist as safe.
|
||||||
|
* @param string[] $sanitized_keys
|
||||||
|
* An array of keys that have been removed.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* The sanitized input.
|
||||||
|
*/
|
||||||
|
protected static function stripDangerousValues($input, array $whitelist, array &$sanitized_keys) {
|
||||||
|
if (is_array($input)) {
|
||||||
|
foreach ($input as $key => $value) {
|
||||||
|
if ($key !== '' && is_string($key) && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) {
|
||||||
|
unset($input[$key]);
|
||||||
|
$sanitized_keys[] = $key;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$input[$key] = self::stripDangerousValues($input[$key], $whitelist, $sanitized_keys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Executable → Regular
+24
-1
@@ -371,8 +371,11 @@ function drupal_session_regenerate() {
|
|||||||
|
|
||||||
if (drupal_session_started()) {
|
if (drupal_session_started()) {
|
||||||
$old_session_id = session_id();
|
$old_session_id = session_id();
|
||||||
|
_drupal_session_regenerate_existing();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
session_id(drupal_random_key());
|
||||||
}
|
}
|
||||||
session_id(drupal_random_key());
|
|
||||||
|
|
||||||
if (isset($old_session_id)) {
|
if (isset($old_session_id)) {
|
||||||
$params = session_get_cookie_params();
|
$params = session_get_cookie_params();
|
||||||
@@ -412,6 +415,26 @@ function drupal_session_regenerate() {
|
|||||||
date_default_timezone_set(drupal_get_user_timezone());
|
date_default_timezone_set(drupal_get_user_timezone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regenerates an existing session.
|
||||||
|
*/
|
||||||
|
function _drupal_session_regenerate_existing() {
|
||||||
|
global $user;
|
||||||
|
// Preserve existing settings for the saving of sessions.
|
||||||
|
$original_save_session_status = drupal_save_session();
|
||||||
|
// Turn off saving of sessions.
|
||||||
|
drupal_save_session(FALSE);
|
||||||
|
session_write_close();
|
||||||
|
drupal_session_started(FALSE);
|
||||||
|
// Preserve the user object, as starting a new session will reset it.
|
||||||
|
$original_user = $user;
|
||||||
|
session_id(drupal_random_key());
|
||||||
|
drupal_session_start();
|
||||||
|
$user = $original_user;
|
||||||
|
// Restore the original settings for the saving of sessions.
|
||||||
|
drupal_save_session($original_save_session_status);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Session handler assigned by session_set_save_handler().
|
* Session handler assigned by session_set_save_handler().
|
||||||
*
|
*
|
||||||
|
|||||||
Executable → Regular
+150
-2
@@ -133,7 +133,7 @@ interface DrupalStreamWrapperInterface extends StreamWrapperInterface {
|
|||||||
* @param $uri
|
* @param $uri
|
||||||
* A string containing the URI that should be used for this instance.
|
* A string containing the URI that should be used for this instance.
|
||||||
*/
|
*/
|
||||||
function setUri($uri);
|
public function setUri($uri);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the stream resource URI.
|
* Returns the stream resource URI.
|
||||||
@@ -219,7 +219,6 @@ interface DrupalStreamWrapperInterface extends StreamWrapperInterface {
|
|||||||
public function dirname($uri = NULL);
|
public function dirname($uri = NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drupal stream wrapper base class for local files.
|
* Drupal stream wrapper base class for local files.
|
||||||
*
|
*
|
||||||
@@ -549,6 +548,155 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
|
|||||||
return fclose($this->handle);
|
return fclose($this->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets metadata on the stream.
|
||||||
|
*
|
||||||
|
* WARNING: Do not call this method directly! It will be called internally by
|
||||||
|
* PHP itself when one of the following functions is called on a stream URL:
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* A string containing the URI to the file to set metadata on.
|
||||||
|
* @param int $option
|
||||||
|
* One of:
|
||||||
|
* - STREAM_META_TOUCH: The method was called in response to touch().
|
||||||
|
* - STREAM_META_OWNER_NAME: The method was called in response to chown()
|
||||||
|
* with string parameter.
|
||||||
|
* - STREAM_META_OWNER: The method was called in response to chown().
|
||||||
|
* - STREAM_META_GROUP_NAME: The method was called in response to chgrp().
|
||||||
|
* - STREAM_META_GROUP: The method was called in response to chgrp().
|
||||||
|
* - STREAM_META_ACCESS: The method was called in response to chmod().
|
||||||
|
* @param mixed $value
|
||||||
|
* If option is:
|
||||||
|
* - STREAM_META_TOUCH: Array consisting of two arguments of the touch()
|
||||||
|
* function.
|
||||||
|
* - STREAM_META_OWNER_NAME or STREAM_META_GROUP_NAME: The name of the owner
|
||||||
|
* user/group as string.
|
||||||
|
* - STREAM_META_OWNER or STREAM_META_GROUP: The value of the owner
|
||||||
|
* user/group as integer.
|
||||||
|
* - STREAM_META_ACCESS: The argument of the chmod() as integer.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* Returns TRUE on success or FALSE on failure. If $option is not
|
||||||
|
* implemented, FALSE should be returned.
|
||||||
|
*
|
||||||
|
* @see touch()
|
||||||
|
* @see chmod()
|
||||||
|
* @see chown()
|
||||||
|
* @see chgrp()
|
||||||
|
* @link http://php.net/manual/streamwrapper.stream-metadata.php
|
||||||
|
*/
|
||||||
|
public function stream_metadata($uri, $option, $value) {
|
||||||
|
$target = $this->getLocalPath($uri);
|
||||||
|
$return = FALSE;
|
||||||
|
switch ($option) {
|
||||||
|
case STREAM_META_TOUCH:
|
||||||
|
if (!empty($value)) {
|
||||||
|
$return = touch($target, $value[0], $value[1]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$return = touch($target);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STREAM_META_OWNER_NAME:
|
||||||
|
case STREAM_META_OWNER:
|
||||||
|
$return = chown($target, $value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STREAM_META_GROUP_NAME:
|
||||||
|
case STREAM_META_GROUP:
|
||||||
|
$return = chgrp($target, $value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STREAM_META_ACCESS:
|
||||||
|
$return = chmod($target, $value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ($return) {
|
||||||
|
// For convenience clear the file status cache of the underlying file,
|
||||||
|
// since metadata operations are often followed by file status checks.
|
||||||
|
clearstatcache(TRUE, $target);
|
||||||
|
}
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncate stream.
|
||||||
|
*
|
||||||
|
* Will respond to truncation; e.g., through ftruncate().
|
||||||
|
*
|
||||||
|
* @param int $new_size
|
||||||
|
* The new size.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* TRUE on success, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public function stream_truncate($new_size) {
|
||||||
|
return ftruncate($this->handle, $new_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the underlying stream resource.
|
||||||
|
*
|
||||||
|
* This method is called in response to stream_select().
|
||||||
|
*
|
||||||
|
* @param int $cast_as
|
||||||
|
* Can be STREAM_CAST_FOR_SELECT when stream_select() is calling
|
||||||
|
* stream_cast() or STREAM_CAST_AS_STREAM when stream_cast() is called for
|
||||||
|
* other uses.
|
||||||
|
*
|
||||||
|
* @return resource|false
|
||||||
|
* The underlying stream resource or FALSE if stream_select() is not
|
||||||
|
* supported.
|
||||||
|
*
|
||||||
|
* @see stream_select()
|
||||||
|
* @link http://php.net/manual/streamwrapper.stream-cast.php
|
||||||
|
*/
|
||||||
|
public function stream_cast($cast_as) {
|
||||||
|
return $this->handle ? $this->handle : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change stream options.
|
||||||
|
*
|
||||||
|
* This method is called to set options on the stream.
|
||||||
|
*
|
||||||
|
* Since Windows systems do not allow it and it is not needed for most use
|
||||||
|
* cases anyway, this method is not supported on local files and will trigger
|
||||||
|
* an error and return false. If needed, custom subclasses can provide
|
||||||
|
* OS-specific implementations for advanced use cases.
|
||||||
|
*
|
||||||
|
* @param int $option
|
||||||
|
* One of:
|
||||||
|
* - STREAM_OPTION_BLOCKING: The method was called in response to
|
||||||
|
* stream_set_blocking().
|
||||||
|
* - STREAM_OPTION_READ_TIMEOUT: The method was called in response to
|
||||||
|
* stream_set_timeout().
|
||||||
|
* - STREAM_OPTION_WRITE_BUFFER: The method was called in response to
|
||||||
|
* stream_set_write_buffer().
|
||||||
|
* @param int $arg1
|
||||||
|
* If option is:
|
||||||
|
* - STREAM_OPTION_BLOCKING: The requested blocking mode:
|
||||||
|
* - 1 means blocking.
|
||||||
|
* - 0 means not blocking.
|
||||||
|
* - STREAM_OPTION_READ_TIMEOUT: The timeout in seconds.
|
||||||
|
* - STREAM_OPTION_WRITE_BUFFER: The buffer mode, STREAM_BUFFER_NONE or
|
||||||
|
* STREAM_BUFFER_FULL.
|
||||||
|
* @param int $arg2
|
||||||
|
* If option is:
|
||||||
|
* - STREAM_OPTION_BLOCKING: This option is not set.
|
||||||
|
* - STREAM_OPTION_READ_TIMEOUT: The timeout in microseconds.
|
||||||
|
* - STREAM_OPTION_WRITE_BUFFER: The requested buffer size.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* TRUE on success, FALSE otherwise. If $option is not implemented, FALSE
|
||||||
|
* should be returned.
|
||||||
|
*/
|
||||||
|
public function stream_set_option($option, $arg1, $arg2) {
|
||||||
|
trigger_error('stream_set_option() not supported for local file based stream wrappers', E_USER_WARNING);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for unlink().
|
* Support for unlink().
|
||||||
*
|
*
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
+70
-31
@@ -1776,13 +1776,13 @@ function theme_link($variables) {
|
|||||||
* http://www.w3.org/TR/WCAG-TECHS/H42.html for more information.
|
* http://www.w3.org/TR/WCAG-TECHS/H42.html for more information.
|
||||||
*/
|
*/
|
||||||
function theme_links($variables) {
|
function theme_links($variables) {
|
||||||
$links = $variables['links'];
|
$links = (array) $variables['links'];
|
||||||
$attributes = $variables['attributes'];
|
$attributes = (array) $variables['attributes'];
|
||||||
$heading = $variables['heading'];
|
$heading = $variables['heading'];
|
||||||
global $language_url;
|
global $language_url;
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
if (count($links) > 0) {
|
if (!empty($links)) {
|
||||||
// Treat the heading first if it is present to prepend it to the
|
// Treat the heading first if it is present to prepend it to the
|
||||||
// list of links.
|
// list of links.
|
||||||
if (!empty($heading)) {
|
if (!empty($heading)) {
|
||||||
@@ -1911,7 +1911,7 @@ function theme_breadcrumb($variables) {
|
|||||||
/**
|
/**
|
||||||
* Returns HTML for a table.
|
* Returns HTML for a table.
|
||||||
*
|
*
|
||||||
* @param $variables
|
* @param array $variables
|
||||||
* An associative array containing:
|
* An associative array containing:
|
||||||
* - header: An array containing the table headers. Each element of the array
|
* - header: An array containing the table headers. Each element of the array
|
||||||
* can be either a localized string or an associative array with the
|
* can be either a localized string or an associative array with the
|
||||||
@@ -1948,6 +1948,11 @@ function theme_breadcrumb($variables) {
|
|||||||
* )
|
* )
|
||||||
* );
|
* );
|
||||||
* @endcode
|
* @endcode
|
||||||
|
* - footer: An array of table rows which will be printed within a <tfoot>
|
||||||
|
* tag, in the same format as the rows element (see above).
|
||||||
|
* The structure is the same the one defined for the "rows" key except
|
||||||
|
* that the no_striping boolean has no effect, there is no rows striping
|
||||||
|
* for the table footer.
|
||||||
* - attributes: An array of HTML attributes to apply to the table tag.
|
* - attributes: An array of HTML attributes to apply to the table tag.
|
||||||
* - caption: A localized string to use for the <caption> tag.
|
* - caption: A localized string to use for the <caption> tag.
|
||||||
* - colgroups: An array of column groups. Each element of the array can be
|
* - colgroups: An array of column groups. Each element of the array can be
|
||||||
@@ -1984,8 +1989,11 @@ function theme_breadcrumb($variables) {
|
|||||||
* - sticky: Use a "sticky" table header.
|
* - sticky: Use a "sticky" table header.
|
||||||
* - empty: The message to display in an extra row if table does not have any
|
* - empty: The message to display in an extra row if table does not have any
|
||||||
* rows.
|
* rows.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The HTML output.
|
||||||
*/
|
*/
|
||||||
function theme_table($variables) {
|
function theme_table(array $variables) {
|
||||||
$header = $variables['header'];
|
$header = $variables['header'];
|
||||||
$rows = $variables['rows'];
|
$rows = $variables['rows'];
|
||||||
$attributes = $variables['attributes'];
|
$attributes = $variables['attributes'];
|
||||||
@@ -1995,7 +2003,7 @@ function theme_table($variables) {
|
|||||||
$empty = $variables['empty'];
|
$empty = $variables['empty'];
|
||||||
|
|
||||||
// Add sticky headers, if applicable.
|
// Add sticky headers, if applicable.
|
||||||
if (count($header) && $sticky) {
|
if (!empty($header) && $sticky) {
|
||||||
drupal_add_js('misc/tableheader.js');
|
drupal_add_js('misc/tableheader.js');
|
||||||
// Add 'sticky-enabled' class to the table to identify it for JS.
|
// Add 'sticky-enabled' class to the table to identify it for JS.
|
||||||
// This is needed to target tables constructed by this function.
|
// This is needed to target tables constructed by this function.
|
||||||
@@ -2009,7 +2017,7 @@ function theme_table($variables) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Format the table columns:
|
// Format the table columns:
|
||||||
if (count($colgroups)) {
|
if (!empty($colgroups)) {
|
||||||
foreach ($colgroups as $number => $colgroup) {
|
foreach ($colgroups as $number => $colgroup) {
|
||||||
$attributes = array();
|
$attributes = array();
|
||||||
|
|
||||||
@@ -2044,46 +2052,74 @@ function theme_table($variables) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the 'empty' row message if available.
|
// Add the 'empty' row message if available.
|
||||||
if (!count($rows) && $empty) {
|
if (empty($rows) && $empty) {
|
||||||
$header_count = 0;
|
$header_count = 0;
|
||||||
foreach ($header as $header_cell) {
|
if (!empty($header)) {
|
||||||
if (is_array($header_cell)) {
|
foreach ($header as $header_cell) {
|
||||||
$header_count += isset($header_cell['colspan']) ? $header_cell['colspan'] : 1;
|
if (is_array($header_cell)) {
|
||||||
}
|
$header_count += isset($header_cell['colspan']) ?
|
||||||
else {
|
$header_cell['colspan'] : 1;
|
||||||
$header_count++;
|
}
|
||||||
|
else {
|
||||||
|
$header_count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$rows[] = array(array('data' => $empty, 'colspan' => $header_count, 'class' => array('empty', 'message')));
|
$rows[] = array(
|
||||||
|
array(
|
||||||
|
'data' => $empty,
|
||||||
|
'colspan' => $header_count,
|
||||||
|
'class' => array(
|
||||||
|
'empty',
|
||||||
|
'message'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format the table header:
|
// Format the table header.
|
||||||
if (count($header)) {
|
if (!empty($header)) {
|
||||||
$ts = tablesort_init($header);
|
$ts = tablesort_init($header);
|
||||||
// HTML requires that the thead tag has tr tags in it followed by tbody
|
// HTML requires that the thead tag has tr tags in it followed by tbody
|
||||||
// tags. Using ternary operator to check and see if we have any rows.
|
// tags. Using ternary operator to check and see if we have any rows.
|
||||||
$output .= (count($rows) ? ' <thead><tr>' : ' <tr>');
|
$output .= (!empty($rows) ? ' <thead><tr>' : ' <tr>');
|
||||||
foreach ($header as $cell) {
|
foreach ($header as $cell) {
|
||||||
$cell = tablesort_header($cell, $header, $ts);
|
$cell = tablesort_header($cell, $header, $ts);
|
||||||
$output .= _theme_table_cell($cell, TRUE);
|
$output .= _theme_table_cell($cell, TRUE);
|
||||||
}
|
}
|
||||||
// Using ternary operator to close the tags based on whether or not there are rows
|
// Using ternary operator to close the tags based on whether
|
||||||
$output .= (count($rows) ? " </tr></thead>\n" : "</tr>\n");
|
// or not there are rows.
|
||||||
|
$output .= (!empty($rows) ? " </tr></thead>\n" : "</tr>\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$ts = array();
|
$ts = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format the table rows:
|
// Format the table and footer rows.
|
||||||
if (count($rows)) {
|
$sections = array();
|
||||||
$output .= "<tbody>\n";
|
|
||||||
|
if (!empty($rows)) {
|
||||||
|
$sections['tbody'] = $rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($variables['footer'])) {
|
||||||
|
$sections['tfoot'] = $variables['footer'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// tbody and tfoot have the same structure and are built using the same
|
||||||
|
// procedure.
|
||||||
|
foreach ($sections as $tag => $content) {
|
||||||
|
$output .= "<" . $tag . ">\n";
|
||||||
$flip = array('even' => 'odd', 'odd' => 'even');
|
$flip = array('even' => 'odd', 'odd' => 'even');
|
||||||
$class = 'even';
|
$class = 'even';
|
||||||
foreach ($rows as $number => $row) {
|
$default_no_striping = ($tag === 'tfoot');
|
||||||
// Check if we're dealing with a simple or complex row
|
|
||||||
|
foreach ($content as $number => $row) {
|
||||||
|
// Check if we're dealing with a simple or complex row.
|
||||||
if (isset($row['data'])) {
|
if (isset($row['data'])) {
|
||||||
$cells = $row['data'];
|
$cells = $row['data'];
|
||||||
$no_striping = isset($row['no_striping']) ? $row['no_striping'] : FALSE;
|
$no_striping = isset($row['no_striping']) ?
|
||||||
|
$row['no_striping'] : $default_no_striping;
|
||||||
|
|
||||||
// Set the attributes array and exclude 'data' and 'no_striping'.
|
// Set the attributes array and exclude 'data' and 'no_striping'.
|
||||||
$attributes = $row;
|
$attributes = $row;
|
||||||
@@ -2093,16 +2129,17 @@ function theme_table($variables) {
|
|||||||
else {
|
else {
|
||||||
$cells = $row;
|
$cells = $row;
|
||||||
$attributes = array();
|
$attributes = array();
|
||||||
$no_striping = FALSE;
|
$no_striping = $default_no_striping;
|
||||||
}
|
}
|
||||||
if (count($cells)) {
|
|
||||||
// Add odd/even class
|
if (!empty($cells)) {
|
||||||
|
// Add odd/even class.
|
||||||
if (!$no_striping) {
|
if (!$no_striping) {
|
||||||
$class = $flip[$class];
|
$class = $flip[$class];
|
||||||
$attributes['class'][] = $class;
|
$attributes['class'][] = $class;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build row
|
// Build row.
|
||||||
$output .= ' <tr' . drupal_attributes($attributes) . '>';
|
$output .= ' <tr' . drupal_attributes($attributes) . '>';
|
||||||
$i = 0;
|
$i = 0;
|
||||||
foreach ($cells as $cell) {
|
foreach ($cells as $cell) {
|
||||||
@@ -2112,10 +2149,12 @@ function theme_table($variables) {
|
|||||||
$output .= " </tr>\n";
|
$output .= " </tr>\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$output .= "</tbody>\n";
|
|
||||||
|
$output .= "</" . $tag . ">\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$output .= "</table>\n";
|
$output .= "</table>\n";
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
+26
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Initiates a browser-based installation of Drupal.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the root directory of the Drupal installation.
|
||||||
|
*/
|
||||||
|
define('DRUPAL_ROOT', getcwd());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global flag to indicate the site is in installation mode.
|
||||||
|
*/
|
||||||
|
define('MAINTENANCE_MODE', 'install');
|
||||||
|
|
||||||
|
// Exit early if running an incompatible PHP version to avoid fatal errors.
|
||||||
|
if (version_compare(PHP_VERSION, '5.2.4') < 0) {
|
||||||
|
print 'Your PHP installation is too old. Drupal requires at least PHP 5.2.4. See the <a href="http://drupal.org/requirements">system requirements</a> page for more information.';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the installer.
|
||||||
|
require_once DRUPAL_ROOT . '/includes/install.core.inc';
|
||||||
|
install_drupal();
|
||||||
Executable → Regular
+21
-1
@@ -149,7 +149,7 @@ Drupal.ajax = function (base, element, element_settings) {
|
|||||||
// The 'this' variable will not persist inside of the options object.
|
// The 'this' variable will not persist inside of the options object.
|
||||||
var ajax = this;
|
var ajax = this;
|
||||||
ajax.options = {
|
ajax.options = {
|
||||||
url: ajax.url,
|
url: Drupal.sanitizeAjaxUrl(ajax.url),
|
||||||
data: ajax.submit,
|
data: ajax.submit,
|
||||||
beforeSerialize: function (element_settings, options) {
|
beforeSerialize: function (element_settings, options) {
|
||||||
return ajax.beforeSerialize(element_settings, options);
|
return ajax.beforeSerialize(element_settings, options);
|
||||||
@@ -195,9 +195,29 @@ Drupal.ajax = function (base, element, element_settings) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
|
jsonp: false,
|
||||||
type: 'POST'
|
type: 'POST'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For multipart forms (e.g., file uploads), jQuery Form targets the form
|
||||||
|
// submission to an iframe instead of using an XHR object. The initial "src"
|
||||||
|
// of the iframe, prior to the form submission, is set to options.iframeSrc.
|
||||||
|
// "about:blank" is the semantically correct, standards-compliant, way to
|
||||||
|
// initialize a blank iframe; however, some old IE versions (possibly only 6)
|
||||||
|
// incorrectly report a mixed content warning when iframes with an
|
||||||
|
// "about:blank" src are added to a parent document with an https:// origin.
|
||||||
|
// jQuery Form works around this by defaulting to "javascript:false" instead,
|
||||||
|
// but that breaks on Chrome 83, so here we force the semantically correct
|
||||||
|
// behavior for all browsers except old IE.
|
||||||
|
// @see https://www.drupal.org/project/drupal/issues/3143016
|
||||||
|
// @see https://github.com/jquery-form/form/blob/df9cb101b9c9c085c8d75ad980c7ff1cf62063a1/jquery.form.js#L68
|
||||||
|
// @see https://bugs.chromium.org/p/chromium/issues/detail?id=1084874
|
||||||
|
// @see https://html.spec.whatwg.org/multipage/browsers.html#creating-browsing-contexts
|
||||||
|
// @see https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
|
||||||
|
if (navigator.userAgent.indexOf("MSIE") === -1) {
|
||||||
|
ajax.options.iframeSrc = 'about:blank';
|
||||||
|
}
|
||||||
|
|
||||||
// Bind the ajaxSubmit function to the element event.
|
// Bind the ajaxSubmit function to the element event.
|
||||||
$(ajax.element).bind(element_settings.event, function (event) {
|
$(ajax.element).bind(element_settings.event, function (event) {
|
||||||
if (!Drupal.settings.urlIsAjaxTrusted[ajax.url] && !Drupal.urlIsLocal(ajax.url)) {
|
if (!Drupal.settings.urlIsAjaxTrusted[ajax.url] && !Drupal.urlIsLocal(ajax.url)) {
|
||||||
|
|||||||
Executable → Regular
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |
Executable → Regular
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |
Executable → Regular
Executable → Regular
+2
-1
@@ -297,8 +297,9 @@ Drupal.ACDB.prototype.search = function (searchString) {
|
|||||||
// encodeURIComponent to allow autocomplete search terms to contain slashes.
|
// encodeURIComponent to allow autocomplete search terms to contain slashes.
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
url: db.uri + '/' + Drupal.encodePath(searchString),
|
url: Drupal.sanitizeAjaxUrl(db.uri + '/' + Drupal.encodePath(searchString)),
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
|
jsonp: false,
|
||||||
success: function (matches) {
|
success: function (matches) {
|
||||||
if (typeof matches.status == 'undefined' || matches.status != 0) {
|
if (typeof matches.status == 'undefined' || matches.status != 0) {
|
||||||
db.cache[searchString] = matches;
|
db.cache[searchString] = matches;
|
||||||
|
|||||||
Executable → Regular
@@ -0,0 +1,4 @@
|
|||||||
|
/vendor/
|
||||||
|
/phpunit.xml
|
||||||
|
/.composer.lock
|
||||||
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
language: php
|
||||||
|
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
php:
|
||||||
|
- '5.3'
|
||||||
|
- '5.4'
|
||||||
|
- '5.5'
|
||||||
|
- '5.6'
|
||||||
|
- '7.0'
|
||||||
|
- '7.1'
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- phpenv config-rm xdebug.ini
|
||||||
|
- composer self-update
|
||||||
|
|
||||||
|
install:
|
||||||
|
- composer install
|
||||||
|
|
||||||
|
script: phpunit
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2016 Denis Brumann
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
Polyfill unserialize [](https://travis-ci.org/dbrumann/polyfill-unserialize)
|
||||||
|
===
|
||||||
|
|
||||||
|
Backports unserialize options introduced in PHP 7.0 to older PHP versions.
|
||||||
|
This was originally designed as a Proof of Concept for Symfony Issue [#21090](https://github.com/symfony/symfony/pull/21090).
|
||||||
|
|
||||||
|
You can use this package in projects that rely on PHP versions older than PHP 7.0.
|
||||||
|
In case you are using PHP 7.0+ the original `unserialize()` will be used instead.
|
||||||
|
|
||||||
|
From the [documentation](https://secure.php.net/manual/en/function.unserialize.php):
|
||||||
|
|
||||||
|
> Warning: Do not pass untrusted user input to unserialize(). Unserialization can
|
||||||
|
> result in code being loaded and executed due to object instantiation
|
||||||
|
> and autoloading, and a malicious user may be able to exploit this.
|
||||||
|
|
||||||
|
This warning holds true even when `allowed_classes` is used.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
- PHP 5.3+
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
You can install this package via composer:
|
||||||
|
|
||||||
|
```
|
||||||
|
composer require brumann/polyfill-unserialize "^1.0"
|
||||||
|
```
|
||||||
|
|
||||||
|
Known Issues
|
||||||
|
------------
|
||||||
|
|
||||||
|
There is a mismatch in behavior when `allowed_classes` in `$options` is not
|
||||||
|
of the correct type (array or boolean). PHP 7.1 will issue a warning, whereas
|
||||||
|
PHP 7.0 will not. I opted to copy the behavior of the former.
|
||||||
|
|
||||||
|
Tests
|
||||||
|
-----
|
||||||
|
|
||||||
|
You can run the test suite using PHPUnit. It is intentionally not bundled as
|
||||||
|
dev dependency to make sure this package has the lowest restrictions on the
|
||||||
|
implementing system as possible.
|
||||||
|
|
||||||
|
Please read the [PHPUnit Manual](https://phpunit.de/manual/current/en/installation.html)
|
||||||
|
for information how to install it on your system.
|
||||||
|
|
||||||
|
You can run the test suite as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
phpunit -c phpunit.xml.dist tests/
|
||||||
|
```
|
||||||
|
|
||||||
|
Contributing
|
||||||
|
------------
|
||||||
|
|
||||||
|
This package is considered feature complete. As such I will likely not update it
|
||||||
|
unless there are security issues.
|
||||||
|
|
||||||
|
Should you find any bugs or have questions, feel free to submit an Issue or a Pull Request.
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user