Skip to content

Commit

Permalink
Merge pull request backdrop#13 from backdrop/1.x
Browse files Browse the repository at this point in the history
update
  • Loading branch information
herbdool committed Oct 13, 2020
2 parents f62e3a9 + 8e5673d commit 5ad50a8
Show file tree
Hide file tree
Showing 35 changed files with 286 additions and 100 deletions.
4 changes: 2 additions & 2 deletions .gitignore
@@ -1,8 +1,8 @@
# Ignore this file so it can be changed
# Ignore this file so it can be changed.
.gitignore

# Ignore configuration files that may contain sensitive information.
settings*.php
/settings*.php
sites/*/settings*.php

# Ignore paths that contain user-generated content.
Expand Down
49 changes: 49 additions & 0 deletions .tugboat/config.yml
@@ -0,0 +1,49 @@
services:
php:
image: tugboatqa/php:7.2-apache
default: true
depends: mariadb
commands:
init:
# Install PHP 'zip' extension to allow installing Backdrop modules.
- docker-php-ext-install zip
# Enable Apache 'rewrite' module for clean URLs.
- a2enmod rewrite
# Link the document root to the expected path.
- ln -snf $TUGBOAT_ROOT $DOCROOT
update:
# Use the Tugboat-specific Backdrop settings.
- cp $TUGBOAT_ROOT/.tugboat/settings.local.php $TUGBOAT_ROOT/settings.local.php
# Generate a unique hash_salt to secure the site.
- echo "\$settings['hash_salt'] = '$(openssl rand -hex 32)';" >> $TUGBOAT_ROOT/settings.local.php
# Create the config directories.
- mkdir $TUGBOAT_ROOT/files/config
- mkdir $TUGBOAT_ROOT/files/config/active
- mkdir $TUGBOAT_ROOT/files/config/staging
# Set appropriate file permissions/ownership.
- chown -R www-data:www-data $TUGBOAT_ROOT
- find $TUGBOAT_ROOT/files $TUGBOAT_ROOT/layouts $TUGBOAT_ROOT/modules $TUGBOAT_ROOT/themes -type d -exec chmod 2775 {} \;
- find $TUGBOAT_ROOT/files $TUGBOAT_ROOT/layouts $TUGBOAT_ROOT/modules $TUGBOAT_ROOT/themes -type f -exec chmod 0664 {} \;
build:
# Delete previous comments in the PR.
- cd $TUGBOAT_ROOT/.tugboat && ./delete-comments.sh
# Clear out active config (needed when rebuilding/reinstalling).
- find $TUGBOAT_ROOT/files/config/active -mindepth 1 -delete
# Generate and store a random password for the admin user.
- openssl rand -hex 6 > $TUGBOAT_ROOT/.tugboat/password
# Install Backdrop.
- cd $TUGBOAT_ROOT && ./core/scripts/install.sh --db-url=mysql://tugboat:tugboat@mariadb/tugboat --account-pass=`cat .tugboat/password`
# Fix config permissions after install.
- chown -R www-data:www-data $TUGBOAT_ROOT/files/config/active
- find $TUGBOAT_ROOT/files/config/active -type f -exec chmod 0664 {} \;
# Post a comment in the PR.
- cd $TUGBOAT_ROOT/.tugboat && ./post-comment.sh
mariadb:
image: tugboatqa/mariadb:latest
commands:
init:
# Configure database for UTF-8: https://api.backdropcms.org/database-configuration#utf8mb4
- echo "[mysqld]\ninnodb_large_prefix=true\ninnodb_file_format=barracuda\ninnodb_file_per_table=true" >> /etc/mysql/conf.d/utf8mb.conf
build:
# Drop and re-create the database (needed when rebuilding/reinstalling).
- mysqladmin -f drop tugboat && mysqladmin create tugboat
37 changes: 37 additions & 0 deletions .tugboat/delete-comments.sh
@@ -0,0 +1,37 @@
#!/usr/bin/env php
<?php
/**
* Delete any previous comments in the PR about this preview.
*/

$curl_header = array(
'Authorization: token ' . getenv('BACKDROP_GITHUB_TOKEN'),
'Content-Type: application/json',
'Accept: application/vnd.github.v3+json',
'User-Agent: Backdrop CMS',
);
$text = 'Tugboat has finished building a preview for this pull request!';
$url = getenv('TUGBOAT_DEFAULT_SERVICE_URL');

// Get all comments in this PR.
$ch = curl_init('https://api.github.com/repos/' . getenv('TUGBOAT_GITHUB_OWNER') . '/' . getenv('TUGBOAT_GITHUB_REPO') . '/issues/' . getenv('TUGBOAT_GITHUB_PR') . '/comments');
curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

// Find comments that match the new one we're about to add.
if ($code == 200) {
foreach (json_decode($response) as $comment) {
if (strpos($comment->body, $text) === 0 && strpos($comment->body, $url) !== FALSE) {
// Delete comment.
$ch = curl_init('https://api.github.com/repos/' . getenv('TUGBOAT_GITHUB_OWNER') . '/' . getenv('TUGBOAT_GITHUB_REPO') . '/issues/comments/' . $comment->id);
curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_header);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_exec($ch);
curl_close($ch);
}
}
}
26 changes: 26 additions & 0 deletions .tugboat/post-comment.sh
@@ -0,0 +1,26 @@
#!/usr/bin/env php
<?php
/**
* Post a comment in the PR with login details.
*/

$password = file_get_contents(getenv('TUGBOAT_ROOT') . '/.tugboat/password');
$comment = 'Tugboat has finished building a preview for this pull request!
Website: ' . getenv('TUGBOAT_DEFAULT_SERVICE_URL') . '
Username: admin
Password: ' . $password;

// Post comment to GitHub.
$ch = curl_init('https://api.github.com/repos/' . getenv('TUGBOAT_GITHUB_OWNER') . '/' . getenv('TUGBOAT_GITHUB_REPO') . '/issues/' . getenv('TUGBOAT_GITHUB_PR') . '/comments');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: token ' . getenv('BACKDROP_GITHUB_TOKEN'),
'Content-Type: application/json',
'Accept: application/vnd.github.v3+json',
'User-Agent: Backdrop CMS',
));
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array('body' => $comment)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_exec($ch);
curl_close($ch);
13 changes: 13 additions & 0 deletions .tugboat/settings.local.php
@@ -0,0 +1,13 @@
<?php
// Database.
$database = 'mysql://tugboat:tugboat@mariadb/tugboat';
$database_charset = 'utf8mb4';

// Config.
$config_directories['active'] = 'files/config/active';
$config_directories['staging'] = 'files/config/staging';

// Trusted hosts.
$settings['trusted_host_patterns'] = array('^.+\.tugboat\.qa$');

// Miscellaneous.
2 changes: 1 addition & 1 deletion core/includes/bootstrap.inc
Expand Up @@ -7,7 +7,7 @@
/**
* The current system version.
*/
define('BACKDROP_VERSION', '1.17.x-dev');
define('BACKDROP_VERSION', '1.18.x-dev');

/**
* Core API compatibility.
Expand Down
2 changes: 1 addition & 1 deletion core/includes/install.core.inc
Expand Up @@ -1711,7 +1711,7 @@ function install_finished(&$install_state) {
// Will also trigger indexing of profile-supplied content or feeds.
backdrop_cron_run();

$message = st('Congratulations, you installed @profile!', array('@profile' => backdrop_install_profile_distribution_name()));
$message = st('Thank you for installing @profile!', array('@profile' => backdrop_install_profile_distribution_name()));

if (!backdrop_is_cli()) {
backdrop_set_message($message);
Expand Down
9 changes: 8 additions & 1 deletion core/includes/update.inc
Expand Up @@ -89,10 +89,17 @@ function update_prepare_bootstrap() {
$active_config = config_get_config_storage('active');
$staging_config = config_get_config_storage('staging');

if (!$settings_exist || !$active_config->isInitialized() || !$staging_config->isInitialized()) {
if (!$settings_exist || !$active_config->isInitialized()) {
backdrop_install_config_directories();
}

// Check for a staging directory.
if (!$staging_config->isInitialized()) {
$t = get_t();
backdrop_set_message($t('The staging configuration directory (%directory) could not be found. Please make sure it exists and is properly referenced in settings.php.',
array('%directory' => config_get_config_directory('staging'))), 'warning', FALSE);
}

// If any of the required settings needs to be written, then settings.php
// needs to be writable.
if (!$settings_exist) {
Expand Down
5 changes: 3 additions & 2 deletions core/misc/ajax.js
Expand Up @@ -21,7 +21,7 @@ Backdrop.settings.urlIsAjaxTrusted = Backdrop.settings.urlIsAjaxTrusted || {};
*/
Backdrop.behaviors.AJAX = {
attach: function (context, settings) {

function loadAjaxBehaviour(base) {
if (!$('#' + base + '.ajax-processed').length) {
var element_settings = settings.ajax[base];
Expand Down Expand Up @@ -195,7 +195,7 @@ Backdrop.ajax = function (base, element, element_settings) {
var currentAjaxRequestNumber = 0;
var ajax = this;
ajax.options = {
url: ajax.url,
url: Backdrop.sanitizeAjaxUrl(ajax.url),
data: ajax.submit,
beforeSerialize: function (element_settings, options) {
return ajax.beforeSerialize(element_settings, options);
Expand Down Expand Up @@ -247,6 +247,7 @@ Backdrop.ajax = function (base, element, element_settings) {
}
},
dataType: 'json',
jsonp: false,
accepts: {
json: element_settings.accepts || 'application/vnd.backdrop-ajax'
},
Expand Down
3 changes: 2 additions & 1 deletion core/misc/autocomplete.js
Expand Up @@ -320,8 +320,9 @@ Backdrop.ACDB.prototype.search = function (searchString) {
// Ajax GET request for autocompletion.
$.ajax({
type: 'GET',
url: db.uri + '/' + encodeURIComponent(searchString),
url: Backdrop.sanitizeAjaxUrl(db.uri + '/' + encodeURIComponent(searchString)),
dataType: 'json',
jsonp: false,
success: function (matches) {
if (typeof matches.status === 'undefined' || matches.status !== 0) {
db.cache[searchString] = matches;
Expand Down
17 changes: 17 additions & 0 deletions core/misc/backdrop.js
Expand Up @@ -413,6 +413,23 @@ Backdrop.relativeUrl = function (url) {
return relativeUrl.replace(window.location.protocol + '//' + window.location.hostname + port, '');
};

/**
* Sanitizes a URL for use with jQuery.ajax().
*
* @param url
* The URL string to be sanitized.
*
* @return
* The sanitized URL.
*/
Backdrop.sanitizeAjaxUrl = function (url) {
var regex = /\=\?(&|$)/;
while (url.match(regex)) {
url = url.replace(regex, '');
}
return url;
}

/**
* Returns true if the URL is within Backdrop's base path.
*
Expand Down
Expand Up @@ -168,6 +168,9 @@ CKEDITOR.plugins.add('backdropimagecaption', {
var figure = new CKEDITOR.htmlParser.element('figure');
caption = new CKEDITOR.htmlParser.fragment.fromHtml(caption, 'figcaption');

var captionFilter = new CKEDITOR.filter(widgetDefinition.editables.caption.allowedContent);
captionFilter.applyTo(caption);

// Use Backdrop's data-placeholder attribute to insert a CSS-based,
// translation-ready placeholder for empty captions. Note that it
// also must to be done for new instances (see
Expand Down
2 changes: 1 addition & 1 deletion core/modules/dblog/dblog.admin.inc
Expand Up @@ -69,7 +69,7 @@ function dblog_overview() {
// Cells
array('class' => 'icon'),
t($dblog->type),
format_date($dblog->timestamp, $log_date_format),
format_date($dblog->timestamp, 'custom', $log_date_format),
dblog_format_message($dblog, TRUE),
$user_info,
filter_xss($dblog->link),
Expand Down
42 changes: 22 additions & 20 deletions core/modules/dblog/dblog.install
Expand Up @@ -112,28 +112,30 @@ function dblog_update_1001() {
* Convert the format for dates in the database log.
*/
function dblog_update_1002() {
$t = get_t();
$config = config('system.core');
$log_format = $config->get('log_date_format');
// Removed. See https://github.com/backdrop/backdrop-issues/issues/4614
}

/**
* Restore the format for dates in the database log.
*/
function dblog_update_1003() {
// The "log_date_format" value may be a pattern or a named format.
$core_config = config('system.core');
$log_format = $core_config->get('log_date_format');

$date_format_config = config('system.date');
$date_formats = $date_format_config->get('formats');

// Look for a matching date format to use.
foreach (system_get_date_formats() as $date_format) {
if ($log_format == $date_format['pattern']) {
$config->set('log_date_format', $date_format['name']);
$config->save();
break;
}
// If a named pattern is in use, store its pattern directly.
if (isset($date_formats[$log_format])) {
$core_config->set('log_date_format', $date_formats[$log_format]['pattern']);
$core_config->save();
}

// No matching date format found, so create a custom one.
if ($config->get('log_date_format') == $log_format) {
system_date_format_save(array(
'name' => 'dblog_date_format',
'label' => $t('Database log messages date'),
'pattern' => $log_format,
'module' => 'dblog',
));
$config->set('log_date_format', 'dblog_date_format');
$config->save();
// Remove the previously created named format for logging.
if (isset($date_formats['dblog_date_format'])) {
unset($date_formats['dblog_date_format']);
$date_format_config->set('formats', $date_formats);
$date_format_config->save();
}
}
19 changes: 15 additions & 4 deletions core/modules/dblog/dblog.module
Expand Up @@ -159,12 +159,23 @@ function dblog_form_system_logging_settings_alter(&$form, $form_state) {
'#description' => t('The maximum number of messages to keep in the database log. Requires a <a href="@cron">cron maintenance task</a>.', array('@cron' => url('admin/reports/status')))
);

$format = config_get('system.core', 'log_date_format');
$pattern = isset($form_state['values']['dblog_date_format']) ? $form_state['values']['dblog_date_format'] : $format;
$preview = !empty($pattern) ? t('Displayed as %date', array('%date' => format_date(REQUEST_TIME, 'custom', $pattern))) : '';

$form['dblog_date_format'] = array(
'#type' => 'select',
'#type' => 'textfield',
'#title' => t('Date format for log messages'),
'#description' => t('To add or edit options, visit <a href="@date-time-page">Date and time settings</a>.', array('@date-time-page' => url('admin/config/regional/date-time'))),
'#options' => date_format_type_options(),
'#default_value' => config_get('system.core', 'log_date_format'),
'#maxlength' => 100,
'#description' => t('A date format using PHP date and time codes. See the <a href="@url">PHP manual</a> for available options.', array('@url' => 'http://php.net/manual/function.date.php')),
'#default_value' => $pattern,
'#field_suffix' => '<small class="pattern-preview">' . $preview . '</small>',
'#ajax' => array(
'callback' => 'system_date_time_lookup',
'event' => 'keyup',
'progress' => array('type' => 'none', 'message' => NULL),
'disable' => FALSE,
),
'#required' => TRUE,
'#wrapper_attributes' => array(
'id' => 'date-format-pattern',
Expand Down
12 changes: 6 additions & 6 deletions core/modules/dblog/tests/dblog.test
Expand Up @@ -47,7 +47,7 @@ class DBLogTestCase extends BackdropWebTestCase {
$row_limit = 1000;
$this->verifyRowLimit($row_limit);
// Remove seconds from date so this test is more likely to always pass.
$date_format = 'dblog_date_format';
$date_format = 'M d, Y - j:ia';
$this->verifyDateFormat($date_format);
$this->verifyCron($row_limit);
$this->verifyEvents();
Expand Down Expand Up @@ -83,13 +83,13 @@ class DBLogTestCase extends BackdropWebTestCase {
* The date format to display in the log.
*/
private function verifyDateFormat($date_format) {
// Change the database log date format.
// Change the log date format.
$edit = array();
$edit['dblog_date_format'] = $date_format;
$this->backdropPost('admin/config/development/logging', $edit, t('Save configuration'));
$this->assertResponse(200);

// Check date format variable.
// Check date format config value.
$current_format = config_get('system.core', 'log_date_format');
$this->assertTrue($current_format == $date_format, format_string('[Cache] Date format of @current matches date format of @format', array('@current' => $current_format, '@format' => $date_format)));
}
Expand Down Expand Up @@ -263,13 +263,13 @@ class DBLogTestCase extends BackdropWebTestCase {
// Default display includes name and email address; if too long, the email
// address is replaced by three periods.
$this->assertLogMessage(t('New user: %name (%email).', array('%name' => $name, '%email' => $user->mail)), 'DBLog event was recorded: [add user]');
$this->assertText(format_date($new_user_time, 'dblog_date_format'));
$this->assertText(format_date($new_user_time, 'custom', 'M d, Y - j:ia'));
// Login user.
$this->assertLogMessage(t('Session opened for %name.', array('%name' => $name)), 'DBLog event was recorded: [login user]');
$this->assertText(format_date($login_time, 'dblog_date_format'));
$this->assertText(format_date($login_time, 'custom', 'M d, Y - j:ia'));
// Logout user.
$this->assertLogMessage(t('Session closed for %name.', array('%name' => $name)), 'DBLog event was recorded: [logout user]');
$this->assertText(format_date($logout_time, 'dblog_date_format'));
$this->assertText(format_date($logout_time, 'custom', 'M d, Y - j:ia'));
// Delete user.
$message = t('Deleted user: %name %email.', array('%name' => $name, '%email' => '<' . $user->mail . '>'));
$message_text = truncate_utf8(filter_xss($message, array()), 56, TRUE, TRUE);
Expand Down
5 changes: 5 additions & 0 deletions core/modules/field/field.block.inc
Expand Up @@ -76,6 +76,11 @@ class FieldBlock extends Block {
list($entity_type, $field_name) = explode('-', $this->childDelta);
$entity = $this->contexts[$entity_type]->data;

// Do not render if the entity is not found on this layout.
if (empty($entity)) {
return NULL;
}

// Load the entity type's information for this field.
$field = field_info_instance($entity_type, $field_name, $entity->bundle());

Expand Down

0 comments on commit 5ad50a8

Please sign in to comment.