updated ctools, panels, date, diff
This commit is contained in:
parent
542ac42fca
commit
9acef9d37e
@ -1,166 +0,0 @@
|
||||
|
||||
CHANGELOG for Diff 7.x-2.0+13-dev to 7.x-3.x
|
||||
============================================
|
||||
|
||||
1) System variable names have been changed
|
||||
------------------------------------------
|
||||
|
||||
Considerable changes have occurred.
|
||||
|
||||
2) hook_diff() was removed
|
||||
--------------------------
|
||||
|
||||
This has been replaced by hook_entity_diff() as of Diff 7.x-3.x.
|
||||
|
||||
3) Field diffs are handled independently by Diff and the field module
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Field modules SHOULD NOT implement hook_entity_diff().
|
||||
|
||||
This is complicated and costly in terms of performance.
|
||||
|
||||
Two new field callbacks are defined to handle these.
|
||||
|
||||
a) MODULE_field_diff_view_prepare()
|
||||
|
||||
Optional: If you need to load data, use MODULE_field_diff_view_prepare().
|
||||
|
||||
b) MODULE_field_diff_view()
|
||||
|
||||
Recommended: You should implement this to generate the compared data.
|
||||
|
||||
If there is no corresponding hook for a field, the field comparison will try
|
||||
to guess the value using $item['safe_value'] or $item['value'] properties.
|
||||
|
||||
If you need to make this configurable, there are two additional hooks:
|
||||
|
||||
c) MODULE_field_diff_default_options($field_type)
|
||||
|
||||
You should define any additioal settings here. This shares a global namespace
|
||||
of the diff module, so you can overwrite core Diff settings here too.
|
||||
|
||||
In saying that, take care not to accidentially do this.
|
||||
|
||||
d) MODULE_field_diff_options_form($field_type, $settings)
|
||||
|
||||
This is where you insert Form API elements to configure your option settings.
|
||||
|
||||
4) Field diffs are now configurable
|
||||
-----------------------------------
|
||||
|
||||
Each field type defined by core have configurable settings to control the
|
||||
rendering of the comparison.
|
||||
|
||||
a) Global configuration
|
||||
|
||||
An administration page has been added to handle field type default settings.
|
||||
|
||||
This is the preferred way to configure field settings are these are global to
|
||||
all fields of this type.
|
||||
|
||||
b) View mode display options
|
||||
|
||||
The display "Diff comparison" is used to control the fields that are displayed
|
||||
when comparing different revisions.
|
||||
|
||||
The following is a walk-through on how you would configure the Basic page
|
||||
(page) content types field configuration.
|
||||
|
||||
- Enable "Diff comparison" custom view mode
|
||||
|
||||
Navigate to admin/structure/types/manage/page/display and look at the
|
||||
Custom Display Settings for this view mode. Check and save.
|
||||
|
||||
- Configure the display
|
||||
|
||||
After Saving this page, a new tab appears "Diff comparison", click this or
|
||||
navigate directly to admin/structure/types/manage/page/display/diff_standard
|
||||
|
||||
- You can hide or show the fields that you want to display when doing
|
||||
comparisons.
|
||||
- If the field has no inbuilt diff support, then the renderred field items
|
||||
will be compared.
|
||||
|
||||
5) Standard comparison preview / Inline diff view setting
|
||||
---------------------------------------------------------
|
||||
|
||||
You can set the view modes used to compare the rendered node. This can be found
|
||||
in the Diff settings in the Content Type settings page.
|
||||
|
||||
6) Optional CSS and new Boxes styles
|
||||
------------------------------------
|
||||
|
||||
This takes the styles from WikiPedia to really spice up the diff page.
|
||||
|
||||
7) Optional JScript extras
|
||||
--------------------------
|
||||
|
||||
This spices up the revision checkboxes on the revisions page.
|
||||
|
||||
8) Simple past revision token support
|
||||
-------------------------------------
|
||||
|
||||
Use-case, email notifications when content has changes. If these support tokens,
|
||||
then you can embed Diffs into these emails.
|
||||
|
||||
9) Extensive string review
|
||||
--------------------------
|
||||
See http://drupal.org/node/1785742
|
||||
|
||||
|
||||
10) Inline block settings changes
|
||||
---------------------------------
|
||||
The inline block settings are now in the block configuration page.
|
||||
|
||||
11) And much more...
|
||||
--------------------
|
||||
|
||||
The complete change log follows:
|
||||
|
||||
Diff 7.x-2.x
|
||||
o #888680 by Deciphered, Alan D.: Allow modules to interact via drupal_alter()
|
||||
o #1280892 by Alan D., crea: Diff should track the variables that it defines
|
||||
o #1304658 by Alan D., kari.kaariainen: Remove links and comments from the comparison preview
|
||||
o #1122206 by binford2k, Alan D.: Notices thrown by DiffEngine::process_chunk()
|
||||
o #1175064 by zilverdistel, Alan D.: Provide variables for leading and trailing context
|
||||
o #1673864 by Alan D.: Allow users to bypass the admin theme when viewing comparisons
|
||||
o #1673876 by Alan D.: Use Drupal autoloading for classes
|
||||
o #1673856 by Alan D.: Use hook_form_BASE_FORM_ID_alter() rather than hook_form_alter()
|
||||
o #1673856 by Alan D.: Normalise line endings
|
||||
o #114308 by Alan D.: add jQuery for hiding radios that shouldn't show diffs
|
||||
o #1688840 by Alan D.: Enable new JScript behaviour by default
|
||||
o #372957 by erykmynn, JuliaKM, lsrzj, andrew_rs, alexpott, et al: HTML Strip for Diff, WYSIWYG Friendly
|
||||
(This was refactored in the 7.x-3.x branch from the commited 7.x-2.x code)
|
||||
o #521212 by Alan D., blakehall: Make diff comparison page themable
|
||||
o #1671484 by Alan D.: Show number of lines changed on revisions page
|
||||
o #114699 by smokris, Alan D.: Diff module should support Token
|
||||
o #372957 by c31ck: display either Hide or Show based on what clicking it will do at any time (HTML Strip for Diff)
|
||||
This was altered for the 7.x-3.x branch.
|
||||
o #1807510 & #1825202: Simplify Diff administration
|
||||
o #1812162 by mitchell, Alan D.: 'Highlight changes' block appears on edit form
|
||||
|
||||
Node to Entity changes
|
||||
----------------------
|
||||
These are roughly tracked in the meta issue #1365750 Generalize API and Integrate with core field types
|
||||
|
||||
o (no issue) by Alan D.: Use entity specific system variables.
|
||||
o (no issue) by Alan D.: View mode code, new hooks, new API. Massive patch!
|
||||
|
||||
Resolves:
|
||||
o #248778: Taxonomy diff
|
||||
o #1550698: Diff of "select from list" fields shows change in key, not change in value
|
||||
o #1458814: File (and image) field support
|
||||
o #1418760: Optional setting to honour the display settings
|
||||
o #1347316: Selectable view mode for inline diffs and "Current revision" display view mode
|
||||
o #1458906: Improve performances (of existing 7.x-2.x field rendering)
|
||||
o #1424162: Diff in Taxonomy term description
|
||||
o #1211282: Image diff support
|
||||
|
||||
The following patches will be posted in the corresponding project queues once
|
||||
the 7.x-3.x branch is released:
|
||||
o #1595702 by Alan D., mbilbille: Support of field collection module
|
||||
o #1350604 by Alan D., johaziel: Datetime diff
|
||||
o (no issue) by Alan D.: Email field Diff support
|
||||
o (no issue) by Alan D.: Countries Diff support
|
||||
o (no issue) by Alan D.: Name field Diff support
|
||||
o (no issue) by Alan D.: Link field Diff support
|
@ -41,7 +41,7 @@ class _DiffOp {
|
||||
class _DiffOp_Copy extends _DiffOp {
|
||||
var $type = 'copy';
|
||||
|
||||
function _DiffOp_Copy($orig, $closing = FALSE) {
|
||||
function __construct($orig, $closing = FALSE) {
|
||||
if (!is_array($closing)) {
|
||||
$closing = $orig;
|
||||
}
|
||||
@ -62,7 +62,7 @@ class _DiffOp_Copy extends _DiffOp {
|
||||
class _DiffOp_Delete extends _DiffOp {
|
||||
var $type = 'delete';
|
||||
|
||||
function _DiffOp_Delete($lines) {
|
||||
function __construct($lines) {
|
||||
$this->orig = $lines;
|
||||
$this->closing = FALSE;
|
||||
}
|
||||
@ -80,7 +80,7 @@ class _DiffOp_Delete extends _DiffOp {
|
||||
class _DiffOp_Add extends _DiffOp {
|
||||
var $type = 'add';
|
||||
|
||||
function _DiffOp_Add($lines) {
|
||||
function __construct($lines) {
|
||||
$this->closing = $lines;
|
||||
$this->orig = FALSE;
|
||||
}
|
||||
@ -98,7 +98,7 @@ class _DiffOp_Add extends _DiffOp {
|
||||
class _DiffOp_Change extends _DiffOp {
|
||||
var $type = 'change';
|
||||
|
||||
function _DiffOp_Change($orig, $closing) {
|
||||
function __construct($orig, $closing) {
|
||||
$this->orig = $orig;
|
||||
$this->closing = $closing;
|
||||
}
|
||||
@ -215,11 +215,17 @@ class _DiffEngine {
|
||||
// Find deletes & adds.
|
||||
$delete = array();
|
||||
while ($xi < $n_from && $this->xchanged[$xi]) {
|
||||
$delete[] = $from_lines[$xi++];
|
||||
$_fl = $from_lines[$xi++];
|
||||
if (strlen($_fl)) {
|
||||
$delete[] = $_fl;
|
||||
}
|
||||
}
|
||||
$add = array();
|
||||
while ($yi < $n_to && $this->ychanged[$yi]) {
|
||||
$add[] = $to_lines[$yi++];
|
||||
$_tl = $to_lines[$yi++];
|
||||
if (strlen($_tl)) {
|
||||
$add[] = $_tl;
|
||||
}
|
||||
}
|
||||
if ($delete && $add) {
|
||||
$edits[] = new _DiffOp_Change($delete, $add);
|
||||
@ -576,7 +582,7 @@ class Diff {
|
||||
* (Typically these are lines from a file.)
|
||||
* @param $to_lines array An array of strings.
|
||||
*/
|
||||
function Diff($from_lines, $to_lines) {
|
||||
function __construct($from_lines, $to_lines) {
|
||||
$eng = new _DiffEngine;
|
||||
$this->edits = $eng->diff($from_lines, $to_lines);
|
||||
//$this->_check($from_lines, $to_lines);
|
||||
@ -735,12 +741,11 @@ class MappedDiff extends Diff {
|
||||
* @param $mapped_to_lines array This array should
|
||||
* have the same number of elements as $to_lines.
|
||||
*/
|
||||
function MappedDiff($from_lines, $to_lines, $mapped_from_lines, $mapped_to_lines) {
|
||||
|
||||
function __construct($from_lines, $to_lines, $mapped_from_lines, $mapped_to_lines) {
|
||||
assert(sizeof($from_lines) == sizeof($mapped_from_lines));
|
||||
assert(sizeof($to_lines) == sizeof($mapped_to_lines));
|
||||
|
||||
$this->Diff($mapped_from_lines, $mapped_to_lines);
|
||||
parent::__construct($mapped_from_lines, $mapped_to_lines);
|
||||
|
||||
$xi = $yi = 0;
|
||||
for ($i = 0; $i < sizeof($this->edits); $i++) {
|
||||
@ -950,7 +955,7 @@ define('NBSP', ' '); // iso-8859-x non-breaking space.
|
||||
* @subpackage DifferenceEngine
|
||||
*/
|
||||
class _HWLDF_WordAccumulator {
|
||||
function _HWLDF_WordAccumulator() {
|
||||
function __construct() {
|
||||
$this->_lines = array();
|
||||
$this->_line = '';
|
||||
$this->_group = '';
|
||||
@ -1016,11 +1021,11 @@ class WordLevelDiff extends MappedDiff {
|
||||
return 10000;
|
||||
}
|
||||
|
||||
function WordLevelDiff($orig_lines, $closing_lines) {
|
||||
function __construct($orig_lines, $closing_lines) {
|
||||
list($orig_words, $orig_stripped) = $this->_split($orig_lines);
|
||||
list($closing_words, $closing_stripped) = $this->_split($closing_lines);
|
||||
|
||||
$this->MappedDiff($orig_words, $closing_words, $orig_stripped, $closing_stripped);
|
||||
parent::__construct($orig_words, $closing_words, $orig_stripped, $closing_stripped);
|
||||
}
|
||||
|
||||
function _split($lines) {
|
||||
@ -1095,7 +1100,7 @@ class DrupalDiffFormatter extends DiffFormatter {
|
||||
'offset' => array('x' => 0, 'y' => 0),
|
||||
);
|
||||
|
||||
function DrupalDiffFormatter() {
|
||||
function __construct() {
|
||||
$this->leading_context_lines = variable_get('diff_context_lines_leading', 2);
|
||||
$this->trailing_context_lines = variable_get('diff_context_lines_trailing', 2);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
html.js .diff-js-hidden { display: none; }
|
||||
html.js .diff-js-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Reset as many core themes as possible */
|
||||
table.diff {
|
||||
@ -8,7 +9,7 @@ table.diff {
|
||||
border: 0 none;
|
||||
width: 98%;
|
||||
border-spacing: 5px;
|
||||
table-layout: fixed ;
|
||||
table-layout: fixed;
|
||||
border-collapse: separate;
|
||||
}
|
||||
table.diff tr td:last-child {
|
||||
@ -24,10 +25,13 @@ table.diff th {
|
||||
border-spacing: 4px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
table.diff tr, table.diff tr.even {
|
||||
table.diff tr,
|
||||
table.diff tr.even {
|
||||
background: none;
|
||||
}
|
||||
table.diff tr th, table.diff tr th a, table.diff tr th a:hover {
|
||||
table.diff tr th,
|
||||
table.diff tr th a,
|
||||
table.diff tr th a:hover {
|
||||
color: inherit;
|
||||
font-weight: bold;
|
||||
}
|
||||
@ -37,28 +41,34 @@ table.diff tr.odd {
|
||||
border-style: none;
|
||||
background: transparent;
|
||||
}
|
||||
table.diff th a { display: inline; }
|
||||
table.diff th a {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* Main theming */
|
||||
table.diff, td.diff-number {
|
||||
background-color: white
|
||||
table.diff,
|
||||
td.diff-number {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
table.diff td.diff-lineno {
|
||||
font-weight: bold
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table.diff td.diff-addedline, table.diff td.diff-deletedline, table.diff td.diff-context {
|
||||
table.diff td.diff-addedline,
|
||||
table.diff td.diff-deletedline,
|
||||
table.diff td.diff-context {
|
||||
font-size: 88%;
|
||||
vertical-align: top;
|
||||
white-space: -moz-pre-wrap;
|
||||
white-space: pre-wrap
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
table.diff td.diff-addedline, table.diff td.diff-deletedline {
|
||||
table.diff td.diff-addedline,
|
||||
table.diff td.diff-deletedline {
|
||||
border-style: solid;
|
||||
border-width: 1px 1px 1px 4px;
|
||||
border-radius: 0.33em
|
||||
border-radius: 0.33em;
|
||||
}
|
||||
|
||||
table.diff td.diff-context {
|
||||
@ -76,45 +86,46 @@ table.diff td.diff-addedline {
|
||||
}
|
||||
|
||||
table.diff td.diff-deletedline {
|
||||
border-color: #ffe49c
|
||||
border-color: #ffe49c;
|
||||
}
|
||||
|
||||
.diffchange {
|
||||
font-weight: bold;
|
||||
text-decoration: none
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
table.diff td.diff-addedline .diffchange, table.diff td.diff-deletedline .diffchange {
|
||||
table.diff td.diff-addedline .diffchange,
|
||||
table.diff td.diff-deletedline .diffchange {
|
||||
border-radius: 0.33em;
|
||||
padding: 0.25em 0
|
||||
padding: 0.25em 0;
|
||||
}
|
||||
|
||||
table.diff td.diff-addedline .diffchange {
|
||||
background: #d8ecff
|
||||
background: #d8ecff;
|
||||
}
|
||||
|
||||
table.diff td.diff-deletedline .diffchange {
|
||||
background: #feeec8
|
||||
background: #feeec8;
|
||||
}
|
||||
|
||||
table.diff table.diff td {
|
||||
padding: 0.33em 0.66em
|
||||
padding: 0.33em 0.66em;
|
||||
}
|
||||
|
||||
table.diff td.diff-marker {
|
||||
width: 2%;
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
font-size: 1.25em
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
table.diff col.diff-content {
|
||||
width: 48%
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
table.diff table.diff td div {
|
||||
word-wrap: break-word;
|
||||
overflow: auto
|
||||
overflow: auto;
|
||||
}
|
||||
td.diff-prevlink {
|
||||
text-align: left;
|
||||
@ -122,3 +133,7 @@ td.diff-prevlink {
|
||||
td.diff-nextlink {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
table.diff-revisions tr.revision-published td {
|
||||
background-color: #aaffaa;
|
||||
}
|
||||
|
@ -1,30 +1,47 @@
|
||||
|
||||
html.js .diff-js-hidden { display: none; }
|
||||
html.js .diff-js-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline diff metadata
|
||||
*/
|
||||
.diff-inline-metadata {
|
||||
padding:4px;
|
||||
border:1px solid #ddd;
|
||||
background:#fff;
|
||||
margin:0px 0px 10px;
|
||||
padding: 4px;
|
||||
border: 1px solid #ddd;
|
||||
background: #fff;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.diff-inline-legend { font-size:11px; }
|
||||
.diff-inline-legend {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.diff-inline-legend span,
|
||||
.diff-inline-legend label { margin-right:5px; }
|
||||
.diff-inline-legend label {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline diff markup
|
||||
*/
|
||||
span.diff-deleted { color:#ccc; }
|
||||
span.diff-deleted img { border: solid 2px #ccc; }
|
||||
span.diff-changed { background:#ffb; }
|
||||
span.diff-changed img { border:solid 2px #ffb; }
|
||||
span.diff-added { background:#cfc; }
|
||||
span.diff-added img { border: solid 2px #cfc; }
|
||||
span.diff-deleted {
|
||||
color: #ccc;
|
||||
}
|
||||
span.diff-deleted img {
|
||||
border: solid 2px #ccc;
|
||||
}
|
||||
span.diff-changed {
|
||||
background: #ffb;
|
||||
}
|
||||
span.diff-changed img {
|
||||
border: solid 2px #ffb;
|
||||
}
|
||||
span.diff-added {
|
||||
background: #cfc;
|
||||
}
|
||||
span.diff-added img {
|
||||
border: solid 2px #cfc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traditional split diff theming
|
||||
@ -35,7 +52,8 @@ table.diff {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
table.diff tr.even, table.diff tr.odd {
|
||||
table.diff tr.even,
|
||||
table.diff tr.odd {
|
||||
background-color: inherit;
|
||||
border: none;
|
||||
}
|
||||
@ -45,7 +63,8 @@ td.diff-prevlink {
|
||||
td.diff-nextlink {
|
||||
text-align: right;
|
||||
}
|
||||
td.diff-section-title, div.diff-section-title {
|
||||
td.diff-section-title,
|
||||
div.diff-section-title {
|
||||
background-color: #f0f0ff;
|
||||
font-size: 0.83em;
|
||||
font-weight: bold;
|
||||
@ -84,3 +103,7 @@ table.diff td div {
|
||||
table.diff td {
|
||||
padding: 0.1ex 0.4em;
|
||||
}
|
||||
|
||||
table.diff-revisions tr.revision-published td {
|
||||
background-color: #aaffaa;
|
||||
}
|
||||
|
@ -20,17 +20,6 @@ function diff_admin_settings($form, $form_state) {
|
||||
'#empty_option' => t('- None -'),
|
||||
'#description' => t('Alter the CSS used when displaying diff results.'),
|
||||
);
|
||||
$form['diff_default_state_node'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Diff default state'),
|
||||
'#default_value' => variable_get('diff_default_state_node', 'raw'),
|
||||
'#options' => array(
|
||||
'raw' => t('HTML view'),
|
||||
'raw_plain' => t('Plain view'),
|
||||
),
|
||||
'#empty_option' => t('- None -'),
|
||||
'#description' => t('Default display to show when viewing a diff, html tags in diffed result or as plain text.'),
|
||||
);
|
||||
$form['diff_radio_behavior'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Diff radio behavior'),
|
||||
@ -68,17 +57,50 @@ function diff_admin_settings($form, $form_state) {
|
||||
function diff_admin_global_entity_settings($form, $form_state, $entity_type) {
|
||||
$entity_info = entity_get_info($entity_type);
|
||||
drupal_set_title(t('Diff settings for %entity_label entities', array('%entity_label' => $entity_info['label'])), PASS_THROUGH);
|
||||
|
||||
if ($options = module_invoke_all('entity_diff_options', $entity_type)) {
|
||||
$form['diff_additional_options_' . $entity_type] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => t('Property options'),
|
||||
'#default_value' => variable_get('diff_additional_options_' . $entity_type, array()),
|
||||
'#options' => $options,
|
||||
);
|
||||
}
|
||||
else {
|
||||
$form['diff_additional_options_' . $entity_type] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
$form['diff_show_header_' . $entity_type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Show entity label header'),
|
||||
'#title' => t('Show entity label row header'),
|
||||
'#default_value' => variable_get('diff_show_header_' . $entity_type, 1),
|
||||
);
|
||||
if (user_access('administer permissions')) {
|
||||
$admin_link = l(t('View the administration theme'), 'admin/people/permissions', array('fragment' => 'edit-view-the-administration-theme'));
|
||||
}
|
||||
else {
|
||||
$admin_link = t('View the administration theme');
|
||||
}
|
||||
$form['diff_admin_path_' . $entity_type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Treat diff pages as administrative'),
|
||||
'#description' => t('Diff pages are treated as administrative pages by default, although it is up to each module to enforce this and to implement this optional setting.'),
|
||||
'#title' => t('Use administration theme'),
|
||||
'#description' => t('This option will enable users with the <em>!link</em> permission to use the admin theme when doing comparisons.', array('!link' => $admin_link)),
|
||||
'#default_value' => variable_get('diff_admin_path_' . $entity_type, 1),
|
||||
);
|
||||
$form['diff_default_state_' . $entity_type] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Diff default state'),
|
||||
'#default_value' => variable_get('diff_default_state_' . $entity_type, 'raw'),
|
||||
'#options' => array(
|
||||
'raw' => t('HTML view'),
|
||||
'raw_plain' => t('Plain view'),
|
||||
),
|
||||
'#empty_option' => t('- None -'),
|
||||
'#description' => t('Default display to show when viewing a diff, html tags in diffed result or as plain text.'),
|
||||
);
|
||||
return system_settings_form($form);
|
||||
}
|
||||
|
||||
|
@ -11,27 +11,75 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allow modules to provide a comparison about entities.
|
||||
* Allow modules to provide a comparison about entity properties.
|
||||
*
|
||||
* @param object $old_entity
|
||||
* The older entity revision.
|
||||
*
|
||||
* @param object $new_entity
|
||||
* The newer entity revision.
|
||||
*
|
||||
* @param array $context
|
||||
* An associative array containing:
|
||||
* - entity_type: The entity type; e.g., 'node' or 'user'.
|
||||
* - view_mode: The view mode to use. Defaults to FALSE.
|
||||
* - old_entity: The older entity.
|
||||
* - new_entity: The newer entity.
|
||||
* - view_mode: The view mode to use. Defaults to FALSE. If no view mode is
|
||||
* given, the recommended fallback view mode is 'default'.
|
||||
* - states: An array of view states. These could be one of:
|
||||
* - raw: The raw value of the diff, the classic 7.x-2.x view.
|
||||
* - rendered: The rendered HTML as determined by the view mode. Only
|
||||
* return markup for this state if the value is normally shown
|
||||
* by this view mode. The user will most likely be able to see
|
||||
* the raw or raw_plain state, so this is optional.
|
||||
*
|
||||
* The rendering state is a work in progress.
|
||||
*
|
||||
* Conditionally, you can get these states, but setting these will override
|
||||
* the user selectable markdown method.
|
||||
*
|
||||
* - raw_plain: As raw, but text should be markdowned.
|
||||
* - rendered_plain: As rendered, but text should be markdowned.
|
||||
*
|
||||
* @return array
|
||||
* An associative array of values keyed by the entity property.
|
||||
*
|
||||
* @todo
|
||||
* Investiagate options and document these.
|
||||
* This is effectively an unnested Form API-like structure.
|
||||
*
|
||||
* States are returned as follows:
|
||||
*
|
||||
* $results['line'] = array(
|
||||
* '#name' => t('Line'),
|
||||
* '#states' => array(
|
||||
* 'raw' => array(
|
||||
* '#old' => '<p class="line">This was the old line number [tag].</p>',
|
||||
* '#new' => '<p class="line">This is the new line [tag].</p>',
|
||||
* ),
|
||||
* 'rendered' => array(
|
||||
* '#old' => '<p class="line">This was the old line number <span class="line-number">57</span>.</p>',
|
||||
* '#new' => '<p class="line">This is the new line <span class="line-number">57</span>.</p>',
|
||||
* ),
|
||||
* ),
|
||||
* );
|
||||
*
|
||||
* For backwards compatibility, no changes are required to support states,
|
||||
* but it is recommended to provide a better UI for end users.
|
||||
*
|
||||
* For example, the following example is equivalent to returning the raw
|
||||
* state from the example above.
|
||||
*
|
||||
* $results['line'] = array(
|
||||
* '#name' => t('Line'),
|
||||
* '#old' => '<p class="line">This was the old line number [tag].</p>',
|
||||
* '#new' => '<p class="line">This is the new line [tag].</p>',
|
||||
* );
|
||||
*/
|
||||
function hook_entity_diff($old_entity, $new_entity, $context) {
|
||||
$results = array();
|
||||
|
||||
if ($context['entity_type'] == 'node') {
|
||||
$type = node_type_get_type($new_entity);
|
||||
$result['title'] = array(
|
||||
$results['title'] = array(
|
||||
'#name' => $type->title_label,
|
||||
'#old' => array($old_entity->title),
|
||||
'#new' => array($new_entity->title),
|
||||
@ -41,6 +89,8 @@ function hook_entity_diff($old_entity, $new_entity, $context) {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,7 +107,7 @@ function hook_entity_diff($old_entity, $new_entity, $context) {
|
||||
*
|
||||
* @see hook_entity_diff()
|
||||
*/
|
||||
function hook_entity_diff_alter($entity_diffs, $context) {
|
||||
function hook_entity_diff_alter(&$entity_diffs, $context) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,30 +1,46 @@
|
||||
|
||||
html.js .diff-js-hidden { display:none; }
|
||||
html.js .diff-js-hidden {
|
||||
display:none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline diff metadata
|
||||
*/
|
||||
.diff-inline-metadata {
|
||||
padding:4px;
|
||||
border:1px solid #ddd;
|
||||
background:#fff;
|
||||
margin:0px 0px 10px;
|
||||
}
|
||||
|
||||
.diff-inline-legend { font-size:11px; }
|
||||
padding: 4px;
|
||||
border: 1px solid #ddd;
|
||||
background: #fff;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.diff-inline-legend {
|
||||
font-size: 11px;
|
||||
}
|
||||
.diff-inline-legend span,
|
||||
.diff-inline-legend label { margin-right:5px; }
|
||||
.diff-inline-legend label {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline diff markup
|
||||
*/
|
||||
span.diff-deleted { color:#ccc; }
|
||||
span.diff-deleted img { border: solid 2px #ccc; }
|
||||
span.diff-changed { background:#ffb; }
|
||||
span.diff-changed img { border:solid 2px #ffb; }
|
||||
span.diff-added { background:#cfc; }
|
||||
span.diff-added img { border: solid 2px #cfc; }
|
||||
span.diff-deleted {
|
||||
color: #ccc;
|
||||
}
|
||||
span.diff-deleted img {
|
||||
border: solid 2px #ccc;
|
||||
}
|
||||
span.diff-changed {
|
||||
background: #ffb;
|
||||
}
|
||||
span.diff-changed img {
|
||||
border: solid 2px #ffb;
|
||||
}
|
||||
span.diff-added {
|
||||
background: #cfc;
|
||||
}
|
||||
span.diff-added img {
|
||||
border: solid 2px #cfc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traditional split diff theming
|
||||
@ -35,7 +51,8 @@ table.diff {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
table.diff tr.even, table.diff tr.odd {
|
||||
table.diff tr.even,
|
||||
table.diff tr.odd {
|
||||
background-color: inherit;
|
||||
border: none;
|
||||
}
|
||||
@ -45,7 +62,8 @@ td.diff-prevlink {
|
||||
td.diff-nextlink {
|
||||
text-align: right;
|
||||
}
|
||||
td.diff-section-title, div.diff-section-title {
|
||||
td.diff-section-title,
|
||||
div.diff-section-title {
|
||||
background-color: #f0f0ff;
|
||||
font-size: 0.83em;
|
||||
font-weight: bold;
|
||||
|
@ -12,17 +12,6 @@
|
||||
*
|
||||
* This manually invokes hook_diff() to avoid a function name clash with the
|
||||
* PHP 5 (>= 5.3.0) date_diff() function or the Dates modules implementation.
|
||||
*
|
||||
* @param object $old_entity
|
||||
* The older node revision.
|
||||
* @param object $new_entity
|
||||
* The newer node revision.
|
||||
* @param array $context
|
||||
* An associative array containing:
|
||||
* - entity_type: The entity type; e.g., 'node' or 'user'.
|
||||
* - old_entity: The older entity.
|
||||
* - new_entity: The newer entity.
|
||||
* - view_mode: The view mode to use. Defaults to FALSE.
|
||||
*/
|
||||
function diff_entity_diff($old_entity, $new_entity, $context) {
|
||||
$return = array();
|
||||
@ -52,11 +41,13 @@ function diff_entity_diff($old_entity, $new_entity, $context) {
|
||||
* - old_entity: The older entity.
|
||||
* - new_entity: The newer entity.
|
||||
* - view_mode: The view mode to use. Defaults to FALSE.
|
||||
* @param string $default_langcode
|
||||
* (optional) Language code to force comparison in.
|
||||
*
|
||||
* @return array
|
||||
* An associative array of values keyed by the field name and delta value.
|
||||
*/
|
||||
function diff_entity_fields_diff($old_entity, $new_entity, $context) {
|
||||
function diff_entity_fields_diff($old_entity, $new_entity, $context, $default_langcode = NULL) {
|
||||
$result = array();
|
||||
|
||||
$entity_type = $context['entity_type'];
|
||||
@ -65,7 +56,7 @@ function diff_entity_fields_diff($old_entity, $new_entity, $context) {
|
||||
$field_context = $context;
|
||||
|
||||
$actual_mode = FALSE;
|
||||
list(,, $bundle_name) = entity_extract_ids($entity_type, $new_entity);
|
||||
list(, , $bundle_name) = entity_extract_ids($entity_type, $new_entity);
|
||||
$instances = field_info_instances($entity_type, $bundle_name);
|
||||
|
||||
// Some fields piggy back the display settings, so we need to fake these by
|
||||
@ -98,7 +89,7 @@ function diff_entity_fields_diff($old_entity, $new_entity, $context) {
|
||||
|
||||
// We provide a loose check on the field access.
|
||||
if (field_access('view', $field, $entity_type) || field_access('edit', $field, $entity_type)) {
|
||||
$langcode = field_language($entity_type, $new_entity, $field_name);
|
||||
$langcode = $default_langcode ? $default_langcode : field_language($entity_type, $new_entity, $field_name);
|
||||
|
||||
$field_context['language'] = $langcode;
|
||||
$field_context['field'] = $field;
|
||||
@ -136,10 +127,18 @@ function diff_entity_fields_diff($old_entity, $new_entity, $context) {
|
||||
$func = 'diff_field_diff_view';
|
||||
}
|
||||
|
||||
// Copy the static ID cache to ensure this is the same for each comparison.
|
||||
$original_html_ids = drupal_static('drupal_html_id');
|
||||
$html_ids = &drupal_static('drupal_html_id');
|
||||
|
||||
// These callbacks should be independent of revision.
|
||||
$old_context = $field_context;
|
||||
$old_context['entity'] = $old_entity;
|
||||
$old_values = $func($old_items, $old_context);
|
||||
|
||||
// Restores the ID cache to the original.
|
||||
$html_ids = $original_html_ids;
|
||||
|
||||
$new_context = $field_context;
|
||||
$new_context['entity'] = $new_entity;
|
||||
$new_values = $func($new_items, $new_context);
|
||||
@ -200,22 +199,29 @@ function diff_entity_fields_diff($old_entity, $new_entity, $context) {
|
||||
* An array of strings representing the value, keyed by delta index.
|
||||
*/
|
||||
function diff_field_diff_view($items, $context) {
|
||||
$diff_items = array();
|
||||
$entity = clone $context['entity'];
|
||||
$langcode = field_language($context['entity_type'], $entity, $context['field']['field_name']);
|
||||
$view_mode = empty($context['view_mode']) ? 'diff_standard' : $context['view_mode'];
|
||||
$element = field_view_field($context['entity_type'], $entity, $context['field']['field_name'], $view_mode, $langcode);
|
||||
// Prevent unnecessary rendering of the field. This also prevents issues
|
||||
// where field_view_field() will use a language fallback for display that
|
||||
// may not match the requested diff comparison language.
|
||||
if (!$items) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach (element_children($element) as $delta) {
|
||||
$diff_items[$delta] = drupal_render($element[$delta]);
|
||||
}
|
||||
$diff_items = array();
|
||||
$entity = clone $context['entity'];
|
||||
$langcode = field_language($context['entity_type'], $entity, $context['field']['field_name']);
|
||||
$view_mode = empty($context['view_mode']) ? 'diff_standard' : $context['view_mode'];
|
||||
$element = field_view_field($context['entity_type'], $entity, $context['field']['field_name'], $view_mode, $langcode);
|
||||
|
||||
foreach (element_children($element) as $delta) {
|
||||
$diff_items[$delta] = drupal_render($element[$delta]);
|
||||
}
|
||||
return $diff_items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get the settings for a given field or formatter.
|
||||
*
|
||||
* @param array $context
|
||||
* @param array $field_context
|
||||
* This will get the settings for a field.
|
||||
* - field (required): The field that the items belong to.
|
||||
* - entity: The entity that we are looking up.
|
||||
@ -274,31 +280,6 @@ function diff_global_settings_form(&$subform, $form_state, $type, $settings) {
|
||||
),
|
||||
);
|
||||
|
||||
/*
|
||||
This would be cool, but to do anything else than inline with the text appears
|
||||
to be very hard, requiring a refactoring of both the modules API but also the
|
||||
DiffFormatter and Diff classes. Diff 8.x-4.x maybe.
|
||||
|
||||
$subform['show_delta'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Show delta values'),
|
||||
'#default_value' => $settings['show_delta'],
|
||||
);
|
||||
$subform['delta_format'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('Delta insertion method'),
|
||||
'#default_value' => $settings['delta_format'],
|
||||
'#options' => array(
|
||||
'inline' => t('Prefix to item'),
|
||||
'row' => t('Individual row'),
|
||||
),
|
||||
'#states' => array(
|
||||
'invisible' => array(
|
||||
"input[id$='show-delta']" => array('checked' => FALSE),
|
||||
),
|
||||
),
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
@ -323,11 +304,8 @@ function _diff_field_default_settings($module, $field_type, $settings = array())
|
||||
'markdown' => function_exists($func) ? '' : 'drupal_html_to_text',
|
||||
'line_counter' => '',
|
||||
'show_header' => 1,
|
||||
// Can we? This seems too hard to track in the DiffFormatter as all we
|
||||
// have is a string or an array of strings.
|
||||
//'show_delta' => 0,
|
||||
//'delta_format' => 'row',
|
||||
);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
name = Diff
|
||||
description = Show differences between content revisions.
|
||||
core = 7.x
|
||||
configure = admin/config/content/diff
|
||||
|
||||
files[] = DiffEngine.php
|
||||
|
||||
; Information added by drupal.org packaging script on 2012-11-13
|
||||
version = "7.x-3.2"
|
||||
; Information added by Drupal.org packaging script on 2016-12-20
|
||||
version = "7.x-3.3"
|
||||
core = "7.x"
|
||||
project = "diff"
|
||||
datestamp = "1352784357"
|
||||
datestamp = "1482211686"
|
||||
|
||||
|
@ -5,6 +5,14 @@
|
||||
* Provides uninstallation functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function diff_install() {
|
||||
user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('diff view changes'));
|
||||
user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('diff view changes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
@ -16,6 +24,7 @@ function diff_uninstall() {
|
||||
'diff_view_mode_',
|
||||
'diff_admin_path_',
|
||||
'diff_default_state_',
|
||||
'diff_additional_options_',
|
||||
);
|
||||
foreach ($prefixes as $prefix) {
|
||||
db_delete('variable')
|
||||
@ -55,27 +64,19 @@ function diff_update_7300() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removed diff_update_7301().
|
||||
*/
|
||||
|
||||
/**
|
||||
* Removed diff_update_7302().
|
||||
*/
|
||||
|
||||
/**
|
||||
* Renames some internal settings names.
|
||||
*/
|
||||
function diff_update_7303() {
|
||||
// Get current values
|
||||
// Get current values.
|
||||
$radio = variable_get('diff_script_revisioning', 'simple');
|
||||
$leading = variable_get('diff_leading_context_lines', 2);
|
||||
$trailing = variable_get('diff_trailing_context_lines', 2);
|
||||
// Create new variable names
|
||||
// Create new variable names.
|
||||
variable_set('diff_radio_behavior', $radio);
|
||||
variable_set('diff_context_lines_leading', $leading);
|
||||
variable_set('diff_context_lines_trailing', $trailing);
|
||||
// Delete old variables
|
||||
// Delete old variables.
|
||||
variable_del('diff_script_revisioning');
|
||||
variable_del('diff_leading_context_lines');
|
||||
variable_del('diff_trailing_context_lines');
|
||||
@ -88,8 +89,8 @@ function diff_update_7304() {
|
||||
// This is now always applied to text fields.
|
||||
variable_del('diff_normalise_text');
|
||||
|
||||
// Merge the content type settings for the inline diff block into a single variable.
|
||||
// diff_update_7300() - show_diff_inline_TYPE to diff_show_diff_inline_node_TYPE
|
||||
// Merge the content type settings for the inline diff block into a single
|
||||
// variable.
|
||||
$node_types = array_keys(node_type_get_types());
|
||||
$enabled_types = array();
|
||||
foreach ($node_types as $node_type) {
|
||||
@ -122,3 +123,19 @@ function diff_update_7305() {
|
||||
->condition('name', db_like('diff_view_mode_inline_') . '%', 'LIKE')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the optional additional node properties to render so that the title
|
||||
* still shows by default when doing node comparisons.
|
||||
*/
|
||||
function diff_update_7306() {
|
||||
variable_set('diff_additional_options_node', array('title' => 'title'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Grants access to the Diff "View Changes" button permission to all users.
|
||||
*/
|
||||
function diff_update_7307() {
|
||||
user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('diff view changes'));
|
||||
user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('diff view changes'));
|
||||
}
|
||||
|
@ -39,11 +39,14 @@ function diff_help($path, $arg) {
|
||||
case 'admin/help#diff':
|
||||
$output = '<p>' . t('The Diff module replaces the normal <em>Revisions</em> node tab. Diff enhances the listing of revisions with an option to view the differences between any two content revisions. Access to this feature is controlled with the <em>View revisions</em> permission. The feature can be disabled for an entire content type on the content type configuration page. Diff also provides an optional <em>View changes</em> button while editing a node.') . '</p>';
|
||||
return $output;
|
||||
|
||||
case 'node/%/revisions/%/view':
|
||||
// The translated strings should match node_help('node/%/revisions').
|
||||
return '<p>' . t('Revisions allow you to track differences between multiple versions of your content, and revert back to older versions.') . '</p>';
|
||||
|
||||
case 'node/%/revisions/view/%/%':
|
||||
return '<p>' . t('Comparing two revisions:') . '</p>';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,8 +107,7 @@ function diff_menu() {
|
||||
'page callback' => 'diff_latest',
|
||||
'page arguments' => array(1),
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'access callback' => 'diff_node_revision_access',
|
||||
'access arguments' => array(1),
|
||||
'access arguments' => array('access content'),
|
||||
'tab_parent' => 'node/%/revisions/view',
|
||||
'file' => 'diff.pages.inc',
|
||||
);
|
||||
@ -152,10 +154,20 @@ function diff_menu() {
|
||||
);
|
||||
|
||||
$items['admin/config/content/diff/entities/node'] = array(
|
||||
'title' => 'Node',
|
||||
'title' => 'Nodes',
|
||||
'description' => 'Node comparison settings.',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
'weight' => -10,
|
||||
);
|
||||
$items['admin/config/content/diff/entities/user'] = array(
|
||||
'title' => 'Users',
|
||||
'description' => 'User diff settings.',
|
||||
'file' => 'diff.admin.inc',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('diff_admin_global_entity_settings', 'user'),
|
||||
'access arguments' => array('administer site configuration'),
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
@ -197,6 +209,18 @@ function diff_node_revision_access($node, $op = 'view') {
|
||||
return $may_revision_this_type && _node_revision_access($node, $op);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function diff_permission() {
|
||||
return array(
|
||||
'diff view changes' => array(
|
||||
'title' => t('Access %view button', array('%view' => t('View changes'))),
|
||||
'description' => t('Controls access to the %view button when editing content.', array('%view' => t('View changes'))),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_hook_info().
|
||||
*/
|
||||
@ -238,6 +262,28 @@ function diff_entity_info_alter(&$entity_info) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all the existing revision numbers.
|
||||
*
|
||||
* Clone of node_revision_list() with revision status included. This would be
|
||||
* an additional join in Drupal 8.x to the {node_field_revision} table.
|
||||
*
|
||||
* @param object $node
|
||||
* The node object.
|
||||
*
|
||||
* @return array
|
||||
* An associative array keyed by node revision number.
|
||||
*/
|
||||
function diff_node_revision_list($node) {
|
||||
$revisions = array();
|
||||
$result = db_query('SELECT r.vid, r.title, r.log, r.uid, n.vid AS current_vid, r.status AS status, r.timestamp, u.name FROM {node_revision} r LEFT JOIN {node} n ON n.vid = r.vid INNER JOIN {users} u ON u.uid = r.uid WHERE r.nid = :nid ORDER BY r.vid DESC', array(':nid' => $node->nid));
|
||||
foreach ($result as $revision) {
|
||||
$revisions[$revision->vid] = $revision;
|
||||
}
|
||||
|
||||
return $revisions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_block_info().
|
||||
*/
|
||||
@ -287,7 +333,7 @@ function diff_block_view($delta) {
|
||||
$enabled_types = variable_get('diff_show_diff_inline_node_bundles', array());
|
||||
if (!empty($enabled_types[$node->type])) {
|
||||
$block = array();
|
||||
$revisions = node_revision_list($node);
|
||||
$revisions = diff_node_revision_list($node);
|
||||
if (count($revisions) > 1) {
|
||||
$block['subject'] = t('Highlight changes');
|
||||
$block['content'] = drupal_get_form('diff_inline_form', $node, $revisions);
|
||||
@ -302,7 +348,7 @@ function diff_block_view($delta) {
|
||||
*/
|
||||
function diff_node_view_alter(&$build) {
|
||||
$node = $build['#node'];
|
||||
if (user_access('view revisions') && in_array($node->type, variable_get('diff_show_diff_inline_node_bundles', array()))) {
|
||||
if (user_access('view revisions') && in_array($node->type, variable_get('diff_show_diff_inline_node_bundles', array()), TRUE)) {
|
||||
// Ugly but cheap way to check that we are viewing a node's revision page.
|
||||
if (arg(2) === 'revisions' && arg(3) === $node->vid) {
|
||||
module_load_include('inc', 'diff', 'diff.pages');
|
||||
@ -320,7 +366,9 @@ function diff_node_view_alter(&$build) {
|
||||
function diff_form_node_form_alter(&$form, $form_state) {
|
||||
// Add a 'View changes' button on the node edit form.
|
||||
$node = $form['#node'];
|
||||
if (variable_get('diff_show_preview_changes_node_' . $node->type, TRUE) && !empty($node->nid)) {
|
||||
if (variable_get('diff_show_preview_changes_node_' . $node->type, TRUE)
|
||||
&& user_access('diff view changes')
|
||||
&& !empty($node->nid)) {
|
||||
$form['actions']['preview_changes'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('View changes'),
|
||||
@ -347,6 +395,9 @@ function diff_form_node_type_form_alter(&$form, $form_state) {
|
||||
'#title' => t('Show <em>View changes</em> button on node edit form'),
|
||||
'#weight' => 10,
|
||||
'#default_value' => variable_get('diff_show_preview_changes_node_' . $type->type, TRUE),
|
||||
'#description' => t('You can refine access using the "!perm" permission.', array(
|
||||
'!perm' => t('Access %view button', array('%view' => t('View changes'))),
|
||||
)),
|
||||
);
|
||||
$form['diff']['diff_enable_revisions_page_node'] = array(
|
||||
'#type' => 'checkbox',
|
||||
@ -430,7 +481,7 @@ function diff_node_form_build_preview_changes($form, &$form_state) {
|
||||
$changes = theme('table__diff__preview', array(
|
||||
'header' => $header,
|
||||
'rows' => $rows,
|
||||
'attributes' => array('class' => 'diff'),
|
||||
'attributes' => array('class' => array('diff')),
|
||||
'colgroups' => _diff_default_cols(),
|
||||
'sticky' => FALSE,
|
||||
));
|
||||
@ -440,6 +491,24 @@ function diff_node_form_build_preview_changes($form, &$form_state) {
|
||||
$form_state['rebuild'] = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_features_pipe_COMPONENT_alter().
|
||||
*/
|
||||
function diff_features_pipe_node_alter(&$pipe, $data, $export) {
|
||||
if (!empty($data)) {
|
||||
$variables = array(
|
||||
'diff_show_preview_changes_node',
|
||||
'diff_enable_revisions_page_node',
|
||||
'diff_view_mode_preview_node',
|
||||
);
|
||||
foreach ($data as $node_type) {
|
||||
foreach ($variables as $variable_name) {
|
||||
$pipe['variable'][] = $variable_name . '_' . $node_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
@ -483,7 +552,7 @@ function diff_theme() {
|
||||
* The source string to compare from.
|
||||
* @param string $b
|
||||
* The target string to compare to.
|
||||
* @param boolean $show_header
|
||||
* @param bool $show_header
|
||||
* Display diff context headers. For example, "Line x".
|
||||
* @param array $line_stats
|
||||
* This structure tracks line numbers across multiple calls to DiffFormatter.
|
||||
@ -621,3 +690,85 @@ function diff_build_attachments($jscript = FALSE) {
|
||||
}
|
||||
return $attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_diff() on behalf of the Node module.
|
||||
*/
|
||||
function node_entity_diff($old_node, $new_node, $context) {
|
||||
$result = array();
|
||||
if ($context['entity_type'] == 'node') {
|
||||
module_load_include('inc', 'diff', 'includes/node');
|
||||
$options = variable_get('diff_additional_options_node', array('title' => 'title'));
|
||||
foreach (node_entity_diff_options('node') as $key => $option_label) {
|
||||
if (!empty($options[$key])) {
|
||||
$func = '_node_entity_diff_additional_options_' . $key;
|
||||
$result[$key] = $func($old_node, $new_node, $context);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_diff_options() on behalf of the Node module.
|
||||
*/
|
||||
function node_entity_diff_options($entity_type) {
|
||||
if ($entity_type == 'node') {
|
||||
$options = array(
|
||||
'title' => t('Title field'),
|
||||
// Author field is either the owner or revision creator, neither capture
|
||||
// a change in the author field.
|
||||
'author' => t('Author'),
|
||||
'revision_author' => t('Revision author'),
|
||||
'type' => t('Node type'),
|
||||
'publishing_flags' => t('Publishing options'),
|
||||
// More fields that currently can not be tracked.
|
||||
'created' => t('Created date'),
|
||||
'changed' => t('Updated date'),
|
||||
'revision_timestamp' => t('Revision timestamp'),
|
||||
);
|
||||
if (module_exists('comment')) {
|
||||
$options['comment'] = t('Comment setting');
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_diff() on behalf of the User module.
|
||||
*/
|
||||
function user_entity_diff($old_user, $new_user, $context) {
|
||||
$result = array();
|
||||
if ($context['entity_type'] == 'user') {
|
||||
module_load_include('inc', 'diff', 'includes/user');
|
||||
$options = variable_get('diff_additional_options_user', array(
|
||||
'name' => 'name',
|
||||
'mail' => 'mail',
|
||||
'status' => 'status',
|
||||
));
|
||||
foreach (user_entity_diff_options('user') as $key => $option_label) {
|
||||
if (!empty($options[$key])) {
|
||||
$func = '_user_entity_diff_additional_options_' . $key;
|
||||
$result[$key] = $func($old_user, $new_user, $context);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_diff_options() on behalf of the User module.
|
||||
*/
|
||||
function user_entity_diff_options($entity_type) {
|
||||
if ($entity_type == 'user') {
|
||||
$options = array(
|
||||
'name' => t('Username'),
|
||||
'mail' => t('E-mail address'),
|
||||
'roles' => t('Roles'),
|
||||
'status' => t('Status'),
|
||||
'timezone' => t('Time zone'),
|
||||
'password' => t('Password Hash'),
|
||||
);
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,9 @@
|
||||
*/
|
||||
function diff_latest($node) {
|
||||
$revisions = node_revision_list($node);
|
||||
if (count($revisions) < 2 || !diff_node_revision_access($node, 'view')) {
|
||||
drupal_goto('node/' . $node->nid);
|
||||
}
|
||||
$new = array_shift($revisions);
|
||||
$old = array_shift($revisions);
|
||||
drupal_goto("node/{$node->nid}/revisions/view/{$old->vid}/{$new->vid}");
|
||||
@ -35,19 +38,20 @@ function diff_node_revisions($form, $form_state, $node) {
|
||||
'#value' => $node->nid,
|
||||
);
|
||||
|
||||
$revision_list = node_revision_list($node);
|
||||
$revision_list = diff_node_revision_list($node);
|
||||
$revision_count = count($revision_list);
|
||||
|
||||
if (count($revision_list) > REVISION_LIST_SIZE) {
|
||||
if ($revision_count > REVISION_LIST_SIZE) {
|
||||
// If the list of revisions is longer than the number shown on one page
|
||||
// split the array.
|
||||
$page = isset($_GET['page']) ? $_GET['page'] : '0';
|
||||
$revision_chunks = array_chunk(node_revision_list($node), REVISION_LIST_SIZE);
|
||||
$revision_chunks = array_chunk($revision_list, REVISION_LIST_SIZE);
|
||||
$revisions = $revision_chunks[$page];
|
||||
// Set up global pager variables as would 'pager_query' do.
|
||||
// These variables are then used in the theme('pager') call later.
|
||||
global $pager_page_array, $pager_total, $pager_total_items;
|
||||
$pager_total_items[0] = count($revision_list);
|
||||
$pager_total[0] = ceil(count($revision_list) / REVISION_LIST_SIZE);
|
||||
$pager_total_items[0] = $revision_count;
|
||||
$pager_total[0] = ceil($revision_count / REVISION_LIST_SIZE);
|
||||
$pager_page_array[0] = max(0, min($page, ((int) $pager_total[0]) - 1));
|
||||
}
|
||||
else {
|
||||
@ -73,6 +77,7 @@ function diff_node_revisions($form, $form_state, $node) {
|
||||
'#markup' => t('!date by !username', array(
|
||||
'!date' => l(format_date($revision->timestamp, 'small'), "node/$node->nid"),
|
||||
'!username' => theme('username', array('account' => $revision)))) . $revision_log,
|
||||
'#revision' => $revision,
|
||||
);
|
||||
}
|
||||
else {
|
||||
@ -82,6 +87,7 @@ function diff_node_revisions($form, $form_state, $node) {
|
||||
'!date' => $diff_date,
|
||||
'!username' => theme('username', array('account' => $revision)))
|
||||
) . $revision_log,
|
||||
'#revision' => $revision,
|
||||
);
|
||||
if ($revert_permission) {
|
||||
$operations[] = array(
|
||||
@ -117,23 +123,13 @@ function diff_node_revisions($form, $form_state, $node) {
|
||||
|
||||
$form['submit'] = array('#type' => 'submit', '#value' => t('Compare'));
|
||||
|
||||
if (count($revision_list) > REVISION_LIST_SIZE) {
|
||||
if ($revision_count > REVISION_LIST_SIZE) {
|
||||
$form['#suffix'] = theme('pager');
|
||||
}
|
||||
$form['#attached'] = diff_build_attachments(TRUE);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit code for input form to select two revisions.
|
||||
*/
|
||||
function diff_node_revisions_submit($form, &$form_state) {
|
||||
// The ids are ordered so the old revision is always on the left.
|
||||
$old_vid = min($form_state['values']['old'], $form_state['values']['new']);
|
||||
$new_vid = max($form_state['values']['old'], $form_state['values']['new']);
|
||||
$form_state['redirect'] = 'node/' . $form_state['values']['nid'] . '/revisions/view/' . $old_vid . '/' . $new_vid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for input form to select two revisions.
|
||||
*/
|
||||
@ -145,14 +141,27 @@ function diff_node_revisions_validate($form, &$form_state) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit code for input form to select two revisions.
|
||||
*/
|
||||
function diff_node_revisions_submit($form, &$form_state) {
|
||||
// The ids are ordered so the old revision is always on the left.
|
||||
$old_vid = min($form_state['values']['old'], $form_state['values']['new']);
|
||||
$new_vid = max($form_state['values']['old'], $form_state['values']['new']);
|
||||
if (isset($_GET['destination'])) {
|
||||
unset($_GET['destination']);
|
||||
}
|
||||
$form_state['redirect'] = 'node/' . $form_state['values']['nid'] . '/revisions/view/' . $old_vid . '/' . $new_vid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a comparison for the node between versions 'old_vid' and 'new_vid'.
|
||||
*
|
||||
* @param object $node
|
||||
* Node on which to perform comparison
|
||||
* @param integer $old_vid
|
||||
* Node on which to perform comparison.
|
||||
* @param int $old_vid
|
||||
* Version ID of the old revision.
|
||||
* @param integer $new_vid
|
||||
* @param int $new_vid
|
||||
* Version ID of the new revision.
|
||||
*/
|
||||
function diff_diffs_show($node, $old_vid, $new_vid, $state = NULL) {
|
||||
@ -161,7 +170,7 @@ function diff_diffs_show($node, $old_vid, $new_vid, $state = NULL) {
|
||||
|
||||
$default_state = variable_get('diff_default_state_node', 'raw');
|
||||
if (empty($state)) {
|
||||
$state = $default_state;
|
||||
$state = $default_state;
|
||||
}
|
||||
$state = str_replace('-', '_', $state);
|
||||
if (!array_key_exists($state, diff_available_states())) {
|
||||
@ -279,7 +288,7 @@ function diff_diffs_show($node, $old_vid, $new_vid, $state = NULL) {
|
||||
}
|
||||
$build['diff_preview']['header']['#markup'] = $header;
|
||||
// Don't include node links or comments when viewing the diff.
|
||||
$build['diff_preview']['content'] = node_view($new_node, $view_mode);
|
||||
$build['diff_preview']['content'] = function_exists('entity_view') ? entity_view('node', array($new_node), $view_mode) : node_view($new_node, $view_mode);
|
||||
if (isset($build['diff_preview']['content']['links'])) {
|
||||
unset($build['diff_preview']['content']['links']);
|
||||
}
|
||||
@ -291,33 +300,33 @@ function diff_diffs_show($node, $old_vid, $new_vid, $state = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of rows which represent the difference between nodes.
|
||||
* Creates an array of rows which represent the difference between two entities.
|
||||
*
|
||||
* @param object $old_node
|
||||
* Node for comparison which will be displayed on the left side.
|
||||
* @param object $new_node
|
||||
* Node for comparison which will be displayed on the right side.
|
||||
* @param boolean $state
|
||||
* The state to render for the diff.
|
||||
* @param object $left_entity
|
||||
* Entity for comparison which will be displayed on the left side.
|
||||
* @param object $right_entity
|
||||
* Entity for comparison which will be displayed on the right side.
|
||||
* @param array $context
|
||||
* The context used to render the diff.
|
||||
*/
|
||||
function _diff_body_rows($old_node, $new_node, $state = 'raw') {
|
||||
function diff_entity_body_rows($entity_type, $left_entity, $right_entity, $context = array()) {
|
||||
// This is an unique index only, so no need for drupal_static().
|
||||
static $table_row_counter = 0;
|
||||
|
||||
if ($theme = variable_get('diff_theme', 'default')) {
|
||||
drupal_add_css(drupal_get_path('module', 'diff') . "/css/diff.{$theme}.css");
|
||||
}
|
||||
module_load_include('inc', 'diff', 'includes/node');
|
||||
|
||||
$rows = array();
|
||||
$any_visible_change = FALSE;
|
||||
$context = array(
|
||||
'entity_type' => 'node',
|
||||
'states' => array($state),
|
||||
$context += array(
|
||||
'entity_type' => $entity_type,
|
||||
'states' => array('raw'),
|
||||
'view_mode' => 'diff_standard',
|
||||
);
|
||||
$state = current($context['states']);
|
||||
|
||||
$node_diffs = diff_compare_entities($old_node, $new_node, $context);
|
||||
$entity_diffs = diff_compare_entities($left_entity, $right_entity, $context);
|
||||
|
||||
// Track line numbers between multiple diffs.
|
||||
$line_stats = array(
|
||||
@ -326,19 +335,19 @@ function _diff_body_rows($old_node, $new_node, $state = 'raw') {
|
||||
);
|
||||
|
||||
// Render diffs for each.
|
||||
foreach ($node_diffs as $node_diff) {
|
||||
$show_header = !empty($node_diff['#name']);
|
||||
foreach ($entity_diffs as $entity_diff) {
|
||||
$show_header = !empty($entity_diff['#name']);
|
||||
// These are field level settings.
|
||||
if ($show_header && isset($node_diff['#settings']['show_header'])) {
|
||||
$show_header = $show_header && $node_diff['#settings']['show_header'];
|
||||
if ($show_header && isset($entity_diff['#settings']['show_header'])) {
|
||||
$show_header = $show_header && $entity_diff['#settings']['show_header'];
|
||||
}
|
||||
|
||||
// Line counting and line header options.
|
||||
if (empty($node_diff['#settings']['line_counter'])) {
|
||||
if (empty($entity_diff['#settings']['line_counter'])) {
|
||||
$line_counter = FALSE;
|
||||
}
|
||||
else {
|
||||
$line_counter = $node_diff['#settings']['line_counter'];
|
||||
$line_counter = $entity_diff['#settings']['line_counter'];
|
||||
}
|
||||
// Every call to 'line' resets the counters.
|
||||
if ($line_counter) {
|
||||
@ -354,8 +363,8 @@ function _diff_body_rows($old_node, $new_node, $state = 'raw') {
|
||||
$line_stats_ref = NULL;
|
||||
}
|
||||
|
||||
list($old, $new) = diff_extract_state($node_diff, $state);
|
||||
if ($node_diff_rows = diff_get_rows($old, $new, $line_counter && $line_counter != 'hidden', $line_stats_ref)) {
|
||||
list($left, $right) = diff_extract_state($entity_diff, $state);
|
||||
if ($entity_diff_rows = diff_get_rows($left, $right, $line_counter && $line_counter != 'hidden', $line_stats_ref)) {
|
||||
if ($line_counter && $line_counter != 'line') {
|
||||
$line_stats['offset']['x'] += $line_stats_ref['counter']['x'];
|
||||
$line_stats['offset']['y'] += $line_stats_ref['counter']['y'];
|
||||
@ -363,7 +372,7 @@ function _diff_body_rows($old_node, $new_node, $state = 'raw') {
|
||||
if ($show_header) {
|
||||
$rows['diff-header-' . $table_row_counter++] = array(
|
||||
array(
|
||||
'data' => t('Changes to %name', array('%name' => $node_diff['#name'])),
|
||||
'data' => t('Changes to %name', array('%name' => $entity_diff['#name'])),
|
||||
'class' => 'diff-section-title',
|
||||
'colspan' => 4,
|
||||
),
|
||||
@ -371,7 +380,7 @@ function _diff_body_rows($old_node, $new_node, $state = 'raw') {
|
||||
}
|
||||
// To avoid passing counter to the Diff engine, index rows manually here
|
||||
// to allow modules to interact with the table. i.e. no array_merge().
|
||||
foreach ($node_diff_rows as $row) {
|
||||
foreach ($entity_diff_rows as $row) {
|
||||
$rows['diff-row-' . $table_row_counter++] = $row;
|
||||
}
|
||||
$any_visible_change = TRUE;
|
||||
@ -385,19 +394,28 @@ function _diff_body_rows($old_node, $new_node, $state = 'raw') {
|
||||
'colspan' => 4,
|
||||
),
|
||||
);
|
||||
// @todo: revise this.
|
||||
// Needed to keep safari happy.
|
||||
$rows['diff-empty-' . $table_row_counter++] = array(
|
||||
array('data' => ''),
|
||||
array('data' => ''),
|
||||
array('data' => ''),
|
||||
array('data' => ''),
|
||||
);
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of rows which represent the difference between nodes.
|
||||
*
|
||||
* @param object $old_node
|
||||
* Node for comparison which will be displayed on the left side.
|
||||
* @param object $new_node
|
||||
* Node for comparison which will be displayed on the right side.
|
||||
* @param bool $state
|
||||
* The state to render for the diff.
|
||||
*/
|
||||
function _diff_body_rows($old_node, $new_node, $state = 'raw') {
|
||||
$context = array(
|
||||
'states' => array($state),
|
||||
'view_mode' => 'diff_standard',
|
||||
);
|
||||
return diff_entity_body_rows('node', $old_node, $new_node, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic callback to compare two entities.
|
||||
*/
|
||||
@ -460,6 +478,9 @@ function diff_compare_entities($left_entity, $right_entity, $context) {
|
||||
if (!isset($diff['#sorted'])) {
|
||||
uasort($diff, 'element_sort');
|
||||
}
|
||||
else {
|
||||
unset($diff['#sorted']);
|
||||
}
|
||||
|
||||
// Process the array and get line counts per field.
|
||||
array_walk($diff, 'diff_process_state_lines');
|
||||
@ -467,6 +488,9 @@ function diff_compare_entities($left_entity, $right_entity, $context) {
|
||||
return $diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get line counts per field.
|
||||
*/
|
||||
function diff_process_state_lines(&$diff, $key) {
|
||||
foreach ($diff['#states'] as $state => $data) {
|
||||
if (isset($data['#old'])) {
|
||||
@ -509,20 +533,29 @@ function diff_markdown_state(&$diff, $state) {
|
||||
}
|
||||
|
||||
if (!isset($plain_old) && isset($old)) {
|
||||
if (is_array($old)) {
|
||||
$diff['#states'][$state . '_plain']['#old'] = $markdown ? array_map($markdown, $old) : $old;
|
||||
}
|
||||
else {
|
||||
$diff['#states'][$state . '_plain']['#old'] = $markdown ? $markdown($old) : $old;
|
||||
}
|
||||
$diff['#states'][$state . '_plain']['#old'] = _diff_apply_markdown($markdown, $old);
|
||||
}
|
||||
if (!isset($plain_new) && isset($new)) {
|
||||
if (is_array($new)) {
|
||||
$diff['#states'][$state . '_plain']['#new'] = $markdown ? array_map($markdown, $new) : $new;
|
||||
}
|
||||
else {
|
||||
$diff['#states'][$state . '_plain']['#new'] = $markdown ? $markdown($new) : $new;
|
||||
$diff['#states'][$state . '_plain']['#new'] = _diff_apply_markdown($markdown, $new);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to clear newlines from the content.
|
||||
*/
|
||||
function _diff_apply_markdown($markdown, $items) {
|
||||
if (!$markdown) {
|
||||
return $items;
|
||||
}
|
||||
if (is_array($items)) {
|
||||
$items = array_map($markdown, $items);
|
||||
foreach ($items as &$item) {
|
||||
$item = trim($item, "\n");
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
else {
|
||||
return trim($markdown($items), "\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -534,7 +567,7 @@ function diff_markdown_state(&$diff, $state) {
|
||||
* @param int $vid
|
||||
* Version ID to look for.
|
||||
*
|
||||
* @return boolean|integer
|
||||
* @return bool|int
|
||||
* Returns FALSE if $vid is the last entry.
|
||||
*/
|
||||
function _diff_get_next_vid($node_revisions, $vid) {
|
||||
@ -553,10 +586,10 @@ function _diff_get_next_vid($node_revisions, $vid) {
|
||||
*
|
||||
* @param array $node_revisions
|
||||
* Array of node revision IDs in descending order.
|
||||
* @param integer $vid
|
||||
* @param int $vid
|
||||
* Version ID to look for.
|
||||
*
|
||||
* @return boolean|integer
|
||||
* @return bool|int
|
||||
* Returns FALSE if $vid is the first entry.
|
||||
*/
|
||||
function _diff_get_previous_vid($node_revisions, $vid) {
|
||||
@ -615,13 +648,13 @@ function _diff_default_header($old_header = '', $new_header = '') {
|
||||
* normally rendered content of the specified revision.
|
||||
*/
|
||||
function diff_inline_show($node, $vid = 0, $metadata = TRUE) {
|
||||
$new_node = $vid ? node_load($node->nid, $vid, TRUE) : clone $node;
|
||||
$new_node = $vid ? node_load($node->nid, $vid) : clone $node;
|
||||
node_build_content($new_node);
|
||||
$new = drupal_render($new_node->content);
|
||||
|
||||
$old = $vid ? _diff_get_previous_vid(node_revision_list($node), $vid) : 0;
|
||||
if ($old) {
|
||||
$old_node = node_load($node->nid, $old, TRUE);
|
||||
$old_node = node_load($node->nid, $old);
|
||||
node_build_content($old_node);
|
||||
$old = drupal_render($old_node->content);
|
||||
$output = $metadata ? theme('diff_inline_metadata', array('node' => $new_node)) : '';
|
||||
|
@ -48,14 +48,21 @@ function theme_diff_node_revisions($vars) {
|
||||
'data' => drupal_render($form['diff']['new'][$key]),
|
||||
'class' => array('revision-current'),
|
||||
);
|
||||
$revision = $form['info'][$key]['#revision'];
|
||||
if ($revision && !empty($revision->status)) {
|
||||
$message = t('This is the published revision.');
|
||||
}
|
||||
else {
|
||||
$message = t('This is the current revision.');
|
||||
}
|
||||
$row[] = array(
|
||||
'data' => t('current revision'),
|
||||
'data' => '<strong>' . $message . '</strong>',
|
||||
'class' => array('revision-current'),
|
||||
'colspan' => '2',
|
||||
);
|
||||
$rows[] = array(
|
||||
'data' => $row,
|
||||
'class' => array('error diff-revision'),
|
||||
'class' => array('revision-published diff-revision'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -64,17 +71,13 @@ function theme_diff_node_revisions($vars) {
|
||||
'header' => $header,
|
||||
'rows' => $rows,
|
||||
'sticky' => FALSE,
|
||||
'attributes' => array('class' => 'diff-revisions'),
|
||||
'attributes' => array('class' => array('diff-revisions')),
|
||||
));
|
||||
|
||||
$output .= drupal_render_children($form);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Theme function for a header line in the diff.
|
||||
*/
|
||||
@ -139,11 +142,15 @@ function theme_diff_inline_chunk($vars) {
|
||||
switch ($vars['type']) {
|
||||
case 'add':
|
||||
return "<span class='diff-added'>{$vars['text']}</span>";
|
||||
|
||||
case 'change':
|
||||
return "<span class='diff-changed'>{$vars['text']}</span>";
|
||||
|
||||
case 'delete':
|
||||
return "<span class='diff-deleted'>{$vars['text']}</span>";
|
||||
|
||||
default:
|
||||
return $vars['text'];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -38,13 +38,13 @@ function diff_tokens($type, $tokens, array $data = array(), array $options = arr
|
||||
// Basic diff standard comparison information.
|
||||
case 'diff':
|
||||
case 'diff-markdown':
|
||||
$revisons = node_revision_list($node);
|
||||
if (count($revisons) == 1) {
|
||||
$revisions = node_revision_list($node);
|
||||
if (count($revisions) == 1) {
|
||||
$replacements[$original] = t('(No previous revision available.)');
|
||||
}
|
||||
else {
|
||||
module_load_include('inc', 'diff', 'diff.pages');
|
||||
$old_vid = _diff_get_previous_vid($revisons, $node->vid);
|
||||
$old_vid = _diff_get_previous_vid($revisions, $node->vid);
|
||||
$state = $name == 'diff' ? 'raw' : 'raw_plain';
|
||||
$build = diff_diffs_show($node, $old_vid, $node->vid, $state);
|
||||
unset($build['diff_table']['#rows']['states']);
|
||||
@ -52,7 +52,10 @@ function diff_tokens($type, $tokens, array $data = array(), array $options = arr
|
||||
unset($build['diff_preview']);
|
||||
|
||||
$output = drupal_render_children($build);
|
||||
$replacements[$original] = $sanitize ? check_plain($output) : $output;
|
||||
if ($sanitize) {
|
||||
$output = filter_xss($output, array('a', 'em', 'strong', 'cite', 'blockquote', 'code', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'table', 'tr', 'th', 'td'));
|
||||
}
|
||||
$replacements[$original] = $output;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -67,7 +67,8 @@ function file_field_diff_view($items, $context) {
|
||||
if ($settings['compare_display_field'] && !empty($field['settings']['display_field'])) {
|
||||
$output['display'] = $item['display'] ? t('Displayed') : t('Hidden');
|
||||
}
|
||||
$diff_items[$delta] = implode('; ', $output);
|
||||
$separator = $settings['property_separator'] == 'nl' ? "\n" : $settings['property_separator'];
|
||||
$diff_items[$delta] = implode($separator, $output);
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,6 +83,7 @@ function file_field_diff_default_options($field_type) {
|
||||
'show_id' => 0,
|
||||
'compare_display_field' => 0,
|
||||
'compare_description_field' => 0,
|
||||
'property_separator' => '; ',
|
||||
);
|
||||
}
|
||||
|
||||
@ -107,5 +109,21 @@ function file_field_diff_options_form($field_type, $settings) {
|
||||
'#default_value' => $settings['compare_display_field'],
|
||||
'#description' => t('This is only used if the "Enable <em>Display</em> field" is checked in the field settings.'),
|
||||
);
|
||||
$options_form['property_separator'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Property separator'),
|
||||
'#default_value' => $settings['property_separator'],
|
||||
'#description' => t('Provides the ability to show properties inline or across multiple lines.'),
|
||||
'#options' => array(
|
||||
', ' => t('Comma (,)'),
|
||||
'; ' => t('Semicolon (;)'),
|
||||
' ' => t('Space'),
|
||||
'nl' => t('New line'),
|
||||
),
|
||||
);
|
||||
// Allow users to set their own separator using variable_set().
|
||||
if (!isset($options_form['#options'][$settings['property_separator']])) {
|
||||
$options_form['#options'][$settings['property_separator']] = $settings['property_separator'];
|
||||
}
|
||||
return $options_form;
|
||||
}
|
||||
|
@ -68,7 +68,8 @@ function image_field_diff_view($items, $context) {
|
||||
if ($settings['show_id']) {
|
||||
$output[] = t('File ID: !fid', $t_args);
|
||||
}
|
||||
$diff_items[$delta] = implode('; ', $output);
|
||||
$separator = $settings['property_separator'] == 'nl' ? "\n" : $settings['property_separator'];
|
||||
$diff_items[$delta] = implode($separator, $output);
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,6 +84,7 @@ function image_field_diff_default_options($field_type) {
|
||||
'show_id' => 0,
|
||||
'compare_alt_field' => 0,
|
||||
'compare_title_field' => 0,
|
||||
'property_separator' => '; ',
|
||||
);
|
||||
}
|
||||
|
||||
@ -108,5 +110,21 @@ function image_field_diff_options_form($field_type, $settings) {
|
||||
'#default_value' => $settings['compare_title_field'],
|
||||
'#description' => t('This is only used if the "Enable <em>Title</em> field" is checked in the instance settings.'),
|
||||
);
|
||||
$options_form['property_separator'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Property separator'),
|
||||
'#default_value' => $settings['property_separator'],
|
||||
'#description' => t('Provides the ability to show properties inline or across multiple lines.'),
|
||||
'#options' => array(
|
||||
', ' => t('Comma (,)'),
|
||||
'; ' => t('Semicolon (;)'),
|
||||
' ' => t('Space'),
|
||||
'nl' => t('New line'),
|
||||
),
|
||||
);
|
||||
// Allow users to set their own separator using variable_set().
|
||||
if (!isset($options_form['#options'][$settings['property_separator']])) {
|
||||
$options_form['#options'][$settings['property_separator']] = $settings['property_separator'];
|
||||
}
|
||||
return $options_form;
|
||||
}
|
||||
|
@ -6,102 +6,199 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_entity_diff().
|
||||
*
|
||||
* This function compares core node properties. This is currently limited to:
|
||||
* - title: The title of the node.
|
||||
*
|
||||
* @param object $old_node
|
||||
* The older node revision.
|
||||
* @param object $new_node
|
||||
* The newer node revision.
|
||||
* @param array $context
|
||||
* An associative array containing:
|
||||
* - entity_type: The entity type; e.g., 'node' or 'user'.
|
||||
* - old_entity: The older entity.
|
||||
* - new_entity: The newer entity.
|
||||
* - view_mode: The view mode to use. Defaults to FALSE. If no view mode is
|
||||
* given, the recommended fallback view mode is 'default'.
|
||||
* - states: An array of view states. These could be one of:
|
||||
* - raw: The raw value of the diff, the classic 7.x-2.x view.
|
||||
* - rendered: The rendered HTML as determined by the view mode. Only
|
||||
* return markup for this state if the value is normally shown
|
||||
* by this view mode. The user will most likely be able to see
|
||||
* the raw or raw_plain state, so this is optional.
|
||||
*
|
||||
* The rendering state is a work in progress.
|
||||
*
|
||||
* Conditionally, you can get these states, but setting these will override
|
||||
* the user selectable markdown method.
|
||||
*
|
||||
* - raw_plain: As raw, but text should be markdowned.
|
||||
* - rendered_plain: As rendered, but text should be markdowned.
|
||||
*
|
||||
* @return array
|
||||
* An associative array of values keyed by the entity property.
|
||||
*
|
||||
* This is effectively an unnested Form API-like structure.
|
||||
*
|
||||
* States are returned as follows:
|
||||
*
|
||||
* $results['line'] = array(
|
||||
* '#name' => t('Line'),
|
||||
* '#states' => array(
|
||||
* 'raw' => array(
|
||||
* '#old' => '<p class="line">This was the old line number [tag].</p>',
|
||||
* '#new' => '<p class="line">This is the new line [tag].</p>',
|
||||
* ),
|
||||
* 'rendered' => array(
|
||||
* '#old' => '<p class="line">This was the old line number <span class="line-number">57</span>.</p>',
|
||||
* '#new' => '<p class="line">This is the new line <span class="line-number">57</span>.</p>',
|
||||
* ),
|
||||
* ),
|
||||
* );
|
||||
*
|
||||
* For backwards compatability, no changes are required to support states,
|
||||
* but it is recommended to provide a better UI for end users.
|
||||
*
|
||||
* For example, the following example is equivalent to returning the raw
|
||||
* state from the example above.
|
||||
*
|
||||
* $results['line'] = array(
|
||||
* '#name' => t('Line'),
|
||||
* '#old' => '<p class="line">This was the old line number [tag].</p>',
|
||||
* '#new' => '<p class="line">This is the new line [tag].</p>',
|
||||
* );
|
||||
* Private callback function to render the title field.
|
||||
*/
|
||||
function node_entity_diff($old_node, $new_node, $context) {
|
||||
$result = array();
|
||||
if ($context['entity_type'] == 'node') {
|
||||
$type = node_type_get_type($new_node);
|
||||
$result['title'] = array(
|
||||
'#name' => $type->title_label,
|
||||
'#states' => array(),
|
||||
'#weight' => -5,
|
||||
'#settings' => array(
|
||||
// Global setting - 'diff_show_header_' . $entity_type
|
||||
'show_header' => variable_get('diff_show_header_node', 1),
|
||||
),
|
||||
);
|
||||
foreach ($context['states'] as $state) {
|
||||
switch ($state) {
|
||||
case 'rendered':
|
||||
$result['title']['#states'][$state] = array(
|
||||
'#old' => l($old_node->title, 'node/' . $old_node->title),
|
||||
'#new' => l($new_node->title, 'node/' . $new_node->title),
|
||||
);
|
||||
break;
|
||||
function _node_entity_diff_additional_options_title($old_node, $new_node, $context) {
|
||||
$type = node_type_get_type($new_node);
|
||||
$row = array(
|
||||
'#name' => $type->title_label,
|
||||
'#states' => array(),
|
||||
'#weight' => -5,
|
||||
'#settings' => array(
|
||||
'show_header' => variable_get('diff_show_header_node', 1),
|
||||
),
|
||||
);
|
||||
foreach ($context['states'] as $state) {
|
||||
switch ($state) {
|
||||
case 'rendered':
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => l($old_node->title, 'node/' . $old_node->title),
|
||||
'#new' => l($new_node->title, 'node/' . $new_node->title),
|
||||
);
|
||||
break;
|
||||
|
||||
// We specify a default so that the title is allows compared.
|
||||
case 'raw':
|
||||
default:
|
||||
$result['title']['#states'][$state] = array(
|
||||
'#old' => array($old_node->title),
|
||||
'#new' => array($new_node->title),
|
||||
);
|
||||
break;
|
||||
}
|
||||
// We specify a default so that the title is allows compared.
|
||||
case 'raw':
|
||||
default:
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => array($old_node->title),
|
||||
'#new' => array($new_node->title),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the type field.
|
||||
*/
|
||||
function _node_entity_diff_additional_options_type($old_node, $new_node, $context) {
|
||||
$row = array(
|
||||
'#name' => t('Content type'),
|
||||
'#states' => array(),
|
||||
'#weight' => -4,
|
||||
'#settings' => array(),
|
||||
);
|
||||
$old_type = node_type_get_type($old_node);
|
||||
$new_type = node_type_get_type($new_node);
|
||||
|
||||
foreach ($context['states'] as $state) {
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => array($old_type ? $old_type->name : t('Deleted type !type', array('!type' => $old_node->type))),
|
||||
'#new' => array($new_type ? $new_type->name : t('Deleted type !type', array('!type' => $new_node->type))),
|
||||
);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the author field.
|
||||
*/
|
||||
function _node_entity_diff_additional_options_author($old_node, $new_node, $context) {
|
||||
$old_author = user_load($old_node->uid);
|
||||
$new_author = user_load($new_node->uid);
|
||||
return _node_entity_diff_additional_options_account(t('Author'), $old_author, $new_author, $context, -4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the revision_author field.
|
||||
*/
|
||||
function _node_entity_diff_additional_options_revision_author($old_node, $new_node, $context) {
|
||||
$old_author = user_load($old_node->revision_uid);
|
||||
$new_author = user_load($new_node->revision_uid);
|
||||
return _node_entity_diff_additional_options_account(t('Revision author'), $old_author, $new_author, $context, -3.9);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the author field.
|
||||
*/
|
||||
function _node_entity_diff_additional_options_account($label, $old_author, $new_author, $context, $weight = 0) {
|
||||
$row = array(
|
||||
'#name' => $label,
|
||||
'#states' => array(),
|
||||
'#weight' => $weight,
|
||||
'#settings' => array(),
|
||||
);
|
||||
foreach ($context['states'] as $state) {
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => array($old_author ? format_username($old_author) : t('Deleted user')),
|
||||
'#new' => array($new_author ? format_username($new_author) : t('Deleted user')),
|
||||
);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the status, sticky and published field.
|
||||
*/
|
||||
function _node_entity_diff_additional_options_publishing_flags($old_node, $new_node, $context) {
|
||||
$row = array(
|
||||
'#name' => t('Publishing options'),
|
||||
'#states' => array(),
|
||||
'#weight' => -3,
|
||||
'#settings' => array(),
|
||||
);
|
||||
$old_options = array($old_node->status ? t('Published') : t('Unpublished'));
|
||||
if ($old_node->promote) {
|
||||
$old_options[] = t('Promoted to front page');
|
||||
}
|
||||
if ($old_node->sticky) {
|
||||
$old_options[] = t('Sticky at top of lists');
|
||||
}
|
||||
|
||||
$new_options = array($new_node->status ? t('Published') : t('Unpublished'));
|
||||
if ($new_node->promote) {
|
||||
$new_options[] = t('Promoted to front page');
|
||||
}
|
||||
if ($new_node->sticky) {
|
||||
$new_options[] = t('Sticky at top of lists');
|
||||
}
|
||||
|
||||
foreach ($context['states'] as $state) {
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => $old_options,
|
||||
'#new' => $new_options,
|
||||
);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the created field.
|
||||
*/
|
||||
function _node_entity_diff_additional_options_created($old_node, $new_node, $context) {
|
||||
return _node_entity_diff_additional_options_date_field(t('Created timestamp'), $old_node->created, $new_node->created, $context, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the changed field.
|
||||
*/
|
||||
function _node_entity_diff_additional_options_changed($old_node, $new_node, $context) {
|
||||
return _node_entity_diff_additional_options_date_field(t('Changed timestamp'), $old_node->changed, $new_node->changed, $context, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the revision_timestamp field.
|
||||
*/
|
||||
function _node_entity_diff_additional_options_revision_timestamp($old_node, $new_node, $context) {
|
||||
return _node_entity_diff_additional_options_date_field(t('Revision timestamp'), $old_node->revision_timestamp, $new_node->revision_timestamp, $context, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to render the date flags.
|
||||
*/
|
||||
function _node_entity_diff_additional_options_date_field($label, $old_date, $new_date, $context, $weight = 0) {
|
||||
$row = array(
|
||||
'#name' => $label,
|
||||
'#states' => array(),
|
||||
'#weight' => $weight,
|
||||
'#settings' => array(),
|
||||
);
|
||||
|
||||
foreach ($context['states'] as $state) {
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => array(format_date($old_date)),
|
||||
'#new' => array(format_date($new_date)),
|
||||
);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the comment field.
|
||||
*/
|
||||
function _node_entity_diff_additional_options_comment($old_node, $new_node, $context) {
|
||||
if (!module_exists('comment')) {
|
||||
return array();
|
||||
}
|
||||
$row = array(
|
||||
'#name' => t('Comment setting'),
|
||||
'#states' => array(),
|
||||
'#weight' => -1,
|
||||
'#settings' => array(),
|
||||
);
|
||||
$options = array(
|
||||
COMMENT_NODE_OPEN => t('Open'),
|
||||
COMMENT_NODE_CLOSED => t('Closed'),
|
||||
COMMENT_NODE_HIDDEN => t('Hidden'),
|
||||
);
|
||||
|
||||
foreach ($context['states'] as $state) {
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => array($options[$old_node->comment]),
|
||||
'#new' => array($options[$new_node->comment]),
|
||||
);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
148
sites/all/modules/contrib/content/diff/includes/user.inc
Normal file
148
sites/all/modules/contrib/content/diff/includes/user.inc
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provide diff functions for the user module.
|
||||
*
|
||||
* Note as users do not have revisions enabled, most use cases for comparisons
|
||||
* will be between two different users.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Private callback function to render the name field.
|
||||
*/
|
||||
function _user_entity_diff_additional_options_name($old_user, $new_user, $context) {
|
||||
$row = array(
|
||||
'#name' => t('Username'),
|
||||
'#states' => array(),
|
||||
'#weight' => -5,
|
||||
'#settings' => array(
|
||||
'show_header' => variable_get('diff_show_header_user', 1),
|
||||
),
|
||||
);
|
||||
foreach ($context['states'] as $state) {
|
||||
switch ($state) {
|
||||
case 'rendered':
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => theme('username', array('account' => $old_user)),
|
||||
'#new' => theme('username', array('account' => $old_user)),
|
||||
);
|
||||
break;
|
||||
|
||||
// We specify a default so that the name is always compared.
|
||||
case 'raw':
|
||||
default:
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => array($old_user->name),
|
||||
'#new' => array($new_user->name),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the mail field.
|
||||
*/
|
||||
function _user_entity_diff_additional_options_mail($old_user, $new_user, $context) {
|
||||
$row = array(
|
||||
'#name' => t('E-mail address'),
|
||||
'#states' => array(),
|
||||
'#weight' => -4,
|
||||
'#settings' => array(),
|
||||
);
|
||||
|
||||
foreach ($context['states'] as $state) {
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => array($old_user->mail),
|
||||
'#new' => array($new_user->mail),
|
||||
);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the status field.
|
||||
*/
|
||||
function _user_entity_diff_additional_options_status($old_user, $new_user, $context) {
|
||||
$row = array(
|
||||
'#name' => t('Status'),
|
||||
'#states' => array(),
|
||||
'#weight' => -3,
|
||||
'#settings' => array(),
|
||||
);
|
||||
|
||||
foreach ($context['states'] as $state) {
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => array($old_user->status ? t('Active') : t('Blocked')),
|
||||
'#new' => array($new_user->status ? t('Active') : t('Blocked')),
|
||||
);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the timezone field.
|
||||
*/
|
||||
function _user_entity_diff_additional_options_timezone($old_user, $new_user, $context) {
|
||||
$row = array(
|
||||
'#name' => t('Time zone'),
|
||||
'#states' => array(),
|
||||
'#weight' => -1,
|
||||
'#settings' => array(),
|
||||
);
|
||||
$system_time_zones = system_time_zones(TRUE);
|
||||
$old_zone = isset($old_user->timezone) ? $old_user->timezone : '';
|
||||
$new_zone = isset($new_user->timezone) ? $new_user->timezone : '';
|
||||
|
||||
foreach ($context['states'] as $state) {
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => array(isset($system_time_zones[$old_zone]) ? $system_time_zones[$old_zone] : t('- None selected -')),
|
||||
'#new' => array(isset($system_time_zones[$new_zone]) ? $system_time_zones[$new_zone] : t('- None selected -')),
|
||||
);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the password field.
|
||||
*/
|
||||
function _user_entity_diff_additional_options_password($old_user, $new_user, $context) {
|
||||
$row = array(
|
||||
'#name' => t('Password Hash'),
|
||||
'#states' => array(),
|
||||
'#weight' => -1,
|
||||
'#settings' => array(),
|
||||
);
|
||||
|
||||
foreach ($context['states'] as $state) {
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => array($old_user->pass),
|
||||
'#new' => array($new_user->pass),
|
||||
);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback function to render the roles field.
|
||||
*/
|
||||
function _user_entity_diff_additional_options_roles($old_user, $new_user, $context) {
|
||||
$row = array(
|
||||
'#name' => t('Roles'),
|
||||
'#states' => array(),
|
||||
'#weight' => -1,
|
||||
'#settings' => array(),
|
||||
);
|
||||
|
||||
$roles = user_roles(TRUE);
|
||||
unset($roles[DRUPAL_AUTHENTICATED_RID]);
|
||||
foreach ($context['states'] as $state) {
|
||||
$row['#states'][$state] = array(
|
||||
'#old' => array(implode("\n", array_intersect_key($roles, $old_user->roles))),
|
||||
'#new' => array(implode("\n", array_intersect_key($roles, $new_user->roles))),
|
||||
);
|
||||
}
|
||||
return $row;
|
||||
}
|
@ -1,58 +1,65 @@
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.diffRevisions = {
|
||||
attach: function (context, settings) {
|
||||
var $rows = $('table.diff-revisions tbody tr');
|
||||
function updateDiffRadios() {
|
||||
var newTd = false;
|
||||
var oldTd = false;
|
||||
if (!$rows.length) {
|
||||
return true;
|
||||
}
|
||||
$rows.removeClass('selected').each(function() {
|
||||
var $row = $(this);
|
||||
$row.removeClass('selected');
|
||||
var $inputs = $row.find('input[type="radio"]');
|
||||
var $oldRadio = $inputs.filter('[name="old"]').eq(0);
|
||||
var $newRadio = $inputs.filter('[name="new"]').eq(0);
|
||||
if (!$oldRadio.length || !$newRadio.length) {
|
||||
"use strict";
|
||||
|
||||
Drupal.behaviors.diffRevisions = {
|
||||
attach: function (context, settings) {
|
||||
var $rows = $('table.diff-revisions tbody tr');
|
||||
function updateDiffRadios() {
|
||||
var newTd = false;
|
||||
var oldTd = false;
|
||||
if (!$rows.length) {
|
||||
return true;
|
||||
}
|
||||
if ($oldRadio.attr('checked')) {
|
||||
oldTd = true;
|
||||
$row.addClass('selected');
|
||||
$oldRadio.css('visibility', 'visible');
|
||||
$newRadio.css('visibility', 'hidden');
|
||||
} else if ($newRadio.attr('checked')) {
|
||||
newTd = true;
|
||||
$row.addClass('selected');
|
||||
$oldRadio.css('visibility', 'hidden');
|
||||
$newRadio.css('visibility', 'visible');
|
||||
} else {
|
||||
if (Drupal.settings.diffRevisionRadios == 'linear') {
|
||||
if (newTd && oldTd) {
|
||||
$oldRadio.css('visibility', 'visible');
|
||||
$newRadio.css('visibility', 'hidden');
|
||||
} else if (newTd) {
|
||||
$newRadio.css('visibility', 'visible');
|
||||
$oldRadio.css('visibility', 'visible');
|
||||
} else {
|
||||
$newRadio.css('visibility', 'visible');
|
||||
$oldRadio.css('visibility', 'hidden');
|
||||
}
|
||||
} else {
|
||||
$newRadio.css('visibility', 'visible');
|
||||
$oldRadio.css('visibility', 'visible');
|
||||
$rows.removeClass('selected').each(function() {
|
||||
var $row = $(this);
|
||||
$row.removeClass('selected');
|
||||
var $inputs = $row.find('input[type="radio"]');
|
||||
var $oldRadio = $inputs.filter('[name="old"]').eq(0);
|
||||
var $newRadio = $inputs.filter('[name="new"]').eq(0);
|
||||
if (!$oldRadio.length || !$newRadio.length) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
if ($oldRadio.attr('checked')) {
|
||||
oldTd = true;
|
||||
$row.addClass('selected');
|
||||
$oldRadio.css('visibility', 'visible');
|
||||
$newRadio.css('visibility', 'hidden');
|
||||
}
|
||||
else if ($newRadio.attr('checked')) {
|
||||
newTd = true;
|
||||
$row.addClass('selected');
|
||||
$oldRadio.css('visibility', 'hidden');
|
||||
$newRadio.css('visibility', 'visible');
|
||||
}
|
||||
else {
|
||||
if (Drupal.settings.diffRevisionRadios == 'linear') {
|
||||
if (newTd && oldTd) {
|
||||
$oldRadio.css('visibility', 'visible');
|
||||
$newRadio.css('visibility', 'hidden');
|
||||
}
|
||||
else if (newTd) {
|
||||
$newRadio.css('visibility', 'visible');
|
||||
$oldRadio.css('visibility', 'visible');
|
||||
}
|
||||
else {
|
||||
$newRadio.css('visibility', 'visible');
|
||||
$oldRadio.css('visibility', 'hidden');
|
||||
}
|
||||
}
|
||||
else {
|
||||
$newRadio.css('visibility', 'visible');
|
||||
$oldRadio.css('visibility', 'visible');
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
if (Drupal.settings.diffRevisionRadios) {
|
||||
$rows.find('input[name="new"], input[name="old"]').click(updateDiffRadios);
|
||||
updateDiffRadios();
|
||||
}
|
||||
}
|
||||
if (Drupal.settings.diffRevisionRadios) {
|
||||
$rows.find('input[name="new"], input[name="old"]').click(updateDiffRadios);
|
||||
updateDiffRadios();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
|
@ -58,13 +58,16 @@ e.g. http://www.example.com/admin/structure/types/manage/page
|
||||
|
||||
i) "Show View changes button on node edit form" adds a new "Preview" like
|
||||
submit button to node editing pages. This shows a diff preview.
|
||||
|
||||
This can be conditionally restricted per role using the user permission
|
||||
"Access View changes button".
|
||||
|
||||
ii) "Enable the Revisions page for this content type" adds the revisioning
|
||||
tab to content. This allows users to compare between various revisions
|
||||
that they have access to.
|
||||
|
||||
iii) "Standard comparison preview" option allows you to control how the most
|
||||
current revision is show on the revision comparision page.
|
||||
current revision is shown on the revision comparison page.
|
||||
|
||||
b) Publishing options
|
||||
|
||||
|
@ -6,9 +6,9 @@ package = Chaos tool suite
|
||||
version = CTOOLS_MODULE_VERSION
|
||||
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
.ctools-button-processed .ctools-content ul {
|
||||
list-style-image: none;
|
||||
list-style-type: none;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.ctools-button-processed li {
|
||||
|
@ -199,7 +199,10 @@ function hook_ctools_render_alter(&$info, &$page, &$context) {
|
||||
* or categories or to rename content on specific sites.
|
||||
*/
|
||||
function hook_ctools_content_subtype_alter($subtype, $plugin) {
|
||||
$subtype['render last'] = TRUE;
|
||||
// Force a particular subtype of a particular plugin to render last.
|
||||
if ($plugin['module'] == 'some_plugin_module' && $plugin['name'] == 'some_plugin_name' && $subtype['subtype_id'] == 'my_subtype_id') {
|
||||
$subtype['render last'] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,11 +6,19 @@ files[] = includes/context.inc
|
||||
files[] = includes/css-cache.inc
|
||||
files[] = includes/math-expr.inc
|
||||
files[] = includes/stylizer.inc
|
||||
files[] = tests/css_cache.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Tests.
|
||||
files[] = tests/context.test
|
||||
files[] = tests/css.test
|
||||
files[] = tests/css_cache.test
|
||||
files[] = tests/ctools.plugins.test
|
||||
files[] = tests/math_expression.test
|
||||
files[] = tests/math_expression_stack.test
|
||||
files[] = tests/object_cache.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -5,9 +5,9 @@ package = Chaos tool suite
|
||||
version = CTOOLS_MODULE_VERSION
|
||||
dependencies[] = ctools
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -5,9 +5,9 @@ version = CTOOLS_MODULE_VERSION
|
||||
dependencies[] = ctools
|
||||
core = 7.x
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -5,9 +5,9 @@ package = Chaos tool suite
|
||||
version = CTOOLS_MODULE_VERSION
|
||||
dependencies[] = ctools
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -8,9 +8,9 @@ dependencies[] = page_manager
|
||||
dependencies[] = advanced_help
|
||||
core = 7.x
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -64,7 +64,7 @@ function ctools_drush_command() {
|
||||
'machine names' => 'Space separated list of exportables you want to view.',
|
||||
),
|
||||
'options' => array(
|
||||
'indent' => 'The string to use for indentation when dispalying the exportable export code. Defaults to \'\'.',
|
||||
'indent' => 'The string to use for indentation when displaying the exportable export code. Defaults to \'\'.',
|
||||
'no-colour' => 'Remove any colour formatting from export string output. Ideal if you are sending the output of this command to a file.',
|
||||
'module' => $module_text,
|
||||
'all' => $all_text,
|
||||
|
@ -155,6 +155,11 @@ function ctools_content_get_subtypes($type) {
|
||||
// Walk through the subtypes and ensure minimal settings are
|
||||
// retained.
|
||||
foreach ($subtypes as $id => $subtype) {
|
||||
// Ensure that the 'subtype_id' value exists.
|
||||
if (!isset($subtype['subtype_id'])) {
|
||||
$subtype['subtype_id'] = $id;
|
||||
}
|
||||
|
||||
// Use exact name since this is a modify by reference.
|
||||
ctools_content_prepare_subtype($subtypes[$id], $plugin);
|
||||
}
|
||||
@ -217,6 +222,7 @@ function ctools_content_prepare_subtype(&$subtype, $plugin) {
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger hook_ctools_content_subtype_alter().
|
||||
drupal_alter('ctools_content_subtype', $subtype, $plugin);
|
||||
}
|
||||
|
||||
@ -241,8 +247,8 @@ function ctools_content_prepare_subtype(&$subtype, $plugin) {
|
||||
* Any incoming content, if this display is a wrapper.
|
||||
*
|
||||
* @return
|
||||
* The content as rendered by the plugin. This content should be an array
|
||||
* with the following possible keys:
|
||||
* The content as rendered by the plugin, or NULL.
|
||||
* This content should be an object with the following possible properties:
|
||||
* - title: The safe to render title of the content.
|
||||
* - title_heading: The title heading.
|
||||
* - content: The safe to render HTML content.
|
||||
|
@ -367,7 +367,6 @@ function ctools_access_ajax_edit($fragment = NULL, $id = NULL) {
|
||||
'contexts' => $contexts,
|
||||
'title' => t('Edit criteria'),
|
||||
'ajax' => TRUE,
|
||||
'ajax' => TRUE,
|
||||
'modal' => TRUE,
|
||||
'modal return' => TRUE,
|
||||
);
|
||||
|
@ -676,14 +676,19 @@ function ctools_context_keyword_substitute($string, $keywords, $contexts, $conve
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($context_keywords[$context]) || !empty($context_keywords[$context]->empty)) {
|
||||
$keywords['%' . $keyword] = '';
|
||||
}
|
||||
else if (!empty($converter)) {
|
||||
$keywords['%' . $keyword] = ctools_context_convert_context($context_keywords[$context], $converter, $converter_options);
|
||||
if (!isset($context_keywords[$context])) {
|
||||
$keywords['%' . $keyword] = '%' . $keyword;
|
||||
}
|
||||
else {
|
||||
$keywords['%' . $keyword] = $context_keywords[$keyword]->title;
|
||||
if (empty($context_keywords[$context]) || !empty($context_keywords[$context]->empty)) {
|
||||
$keywords['%' . $keyword] = '';
|
||||
}
|
||||
else if (!empty($converter)) {
|
||||
$keywords['%' . $keyword] = ctools_context_convert_context($context_keywords[$context], $converter, $converter_options);
|
||||
}
|
||||
else {
|
||||
$keywords['%' . $keyword] = $context_keywords[$keyword]->title;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,18 +200,18 @@ function ctools_plugin_api_get_hook($owner, $api) {
|
||||
/**
|
||||
* Fetch a group of plugins by name.
|
||||
*
|
||||
* @param $module
|
||||
* The name of the module that utilizes this plugin system. It will be
|
||||
* used to call hook_ctools_plugin_$plugin() to get more data about the plugin.
|
||||
* @param $type
|
||||
* @param string $module
|
||||
* The name of the module that utilizes this plugin system. It will be used to
|
||||
* get more data about the plugin as defined on hook_ctools_plugin_type().
|
||||
* @param string $type
|
||||
* The type identifier of the plugin.
|
||||
* @param $id
|
||||
* @param string $id
|
||||
* If specified, return only information about plugin with this identifier.
|
||||
* The system will do its utmost to load only plugins with this id.
|
||||
*
|
||||
* @return
|
||||
* An array of information arrays about the plugins received. The contents
|
||||
* of the array are specific to the plugin.
|
||||
* @return array
|
||||
* An array of information arrays about the plugins received. The contents of
|
||||
* the array are specific to the plugin.
|
||||
*/
|
||||
function ctools_get_plugins($module, $type, $id = NULL) {
|
||||
// Store local caches of plugins and plugin info so we don't have to do full
|
||||
@ -224,10 +224,14 @@ function ctools_get_plugins($module, $type, $id = NULL) {
|
||||
|
||||
$info = ctools_plugin_get_plugin_type_info();
|
||||
|
||||
// Bail out noisily if an invalid module/type combination is requested.
|
||||
if (!isset($info[$module][$type])) {
|
||||
watchdog('ctools', 'Invalid plugin module/type combination requested: module @module and type @type', array('@module' => $module, '@type' => $type), WATCHDOG_ERROR);
|
||||
return array();
|
||||
// If we don't find the plugin we attempt a cache rebuild before bailing out
|
||||
$info = ctools_plugin_get_plugin_type_info(TRUE);
|
||||
// Bail out noisily if an invalid module/type combination is requested.
|
||||
if (!isset($info[$module][$type])) {
|
||||
watchdog('ctools', 'Invalid plugin module/type combination requested: module @module and type @type', array('@module' => $module, '@type' => $type), WATCHDOG_ERROR);
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure our plugins array is populated.
|
||||
@ -235,8 +239,8 @@ function ctools_get_plugins($module, $type, $id = NULL) {
|
||||
$plugins[$module][$type] = array();
|
||||
}
|
||||
|
||||
// Attempt to shortcut this whole piece of code if we already have
|
||||
// the requested plugin:
|
||||
// Attempt to shortcut this whole piece of code if we already have the
|
||||
// requested plugin:
|
||||
if ($id && array_key_exists($id, $plugins[$module][$type])) {
|
||||
return $plugins[$module][$type][$id];
|
||||
}
|
||||
@ -271,8 +275,8 @@ function ctools_get_plugins($module, $type, $id = NULL) {
|
||||
$plugins[$module][$type] = ctools_plugin_load_hooks($info[$module][$type]);
|
||||
}
|
||||
|
||||
// Then see if we should load all files. We only do this if we
|
||||
// want a list of all plugins or there was a cache miss.
|
||||
// Then see if we should load all files. We only do this if we want a list of
|
||||
// all plugins or there was a cache miss.
|
||||
if (empty($setup[$module][$type]) && ($build_cache || !$id)) {
|
||||
$setup[$module][$type] = TRUE;
|
||||
$plugins[$module][$type] = array_merge($plugins[$module][$type], ctools_plugin_load_includes($info[$module][$type]));
|
||||
@ -296,8 +300,8 @@ function ctools_get_plugins($module, $type, $id = NULL) {
|
||||
}
|
||||
|
||||
|
||||
// If we were told earlier that this is cacheable and the cache was
|
||||
// empty, give something back.
|
||||
// If we were told earlier that this is cacheable and the cache was empty,
|
||||
// give something back.
|
||||
if ($build_cache) {
|
||||
cache_set("plugins:$module:$type", $plugins[$module][$type], $info[$module][$type]['cache table']);
|
||||
}
|
||||
|
@ -9,7 +9,9 @@
|
||||
/**
|
||||
* Pattern for detecting a valid UUID.
|
||||
*/
|
||||
define('UUID_PATTERN', '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}');
|
||||
if (!defined('UUID_PATTERN')) {
|
||||
define('UUID_PATTERN', '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a UUID using the Windows internal GUID generator.
|
||||
|
@ -4,7 +4,7 @@ Note: this page is currently very preliminary. Please visit <a href="http://drup
|
||||
This is a quick summary:
|
||||
|
||||
<ul>
|
||||
<li>Visit administer >> site building >> pages to get to the primary page manager interface.</li>
|
||||
<li>Visit administer >> structure >> pages to get to the primary page manager interface.</li>
|
||||
<li>You can add custom pages for your basic landing pages, front pages, whatever you like for normal content display.</li>
|
||||
<li>You can use the system pages to create finer control of how taxonomy vocabularies, nodes and user profiles are displayed.</li>
|
||||
<li>When you add your first custom page, do not bother with the optional features. You will not need these until you get to more advanced tasks.</li>
|
||||
|
@ -1688,6 +1688,12 @@ function page_manager_handler_clone_submit(&$form, &$form_state) {
|
||||
|
||||
page_manager_handler_add_to_page($form_state['page'], $handler, $form_state['values']['title']);
|
||||
|
||||
// Variant is cloned and added to the Page. Ensure the uuids are re-generated.
|
||||
panels_panel_context_get_display($handler);
|
||||
if (isset($handler->conf['display']) && method_exists($handler->conf['display'], 'clone_display')) {
|
||||
$handler->conf['display'] = $handler->conf['display']->clone_display();
|
||||
}
|
||||
|
||||
$plugin = page_manager_get_task_handler($handler->handler);
|
||||
// It has no forms at all. Add the variant and go to its first operation.
|
||||
$keys = array_keys($plugin['operations']);
|
||||
|
@ -5,9 +5,9 @@ dependencies[] = ctools
|
||||
package = Chaos tool suite
|
||||
version = CTOOLS_MODULE_VERSION
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -1462,6 +1462,15 @@ function page_manager_page_form_clone_submit(&$form, &$form_state) {
|
||||
$original->path = $form_state['values']['path'];
|
||||
|
||||
$handlers = !empty($form_state['values']['handlers']) ? $form_state['page']->handlers : FALSE;
|
||||
// Ensure the handler uuids are re-generated.
|
||||
if ($handlers) {
|
||||
foreach ($handlers as &$handler) {
|
||||
if (isset($handler->conf['display']) && method_exists($handler->conf['display'], 'clone_display')) {
|
||||
$handler->conf['display'] = $handler->conf['display']->clone_display();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Export the handler, which is a fantastic way to clean database IDs out of it.
|
||||
$export = page_manager_page_export($original, $handlers);
|
||||
ob_start();
|
||||
|
@ -65,6 +65,7 @@ function ctools_terms_breadcrumb($conf, $context) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current = new stdClass();
|
||||
$current->tid = $context->tids[0];
|
||||
$breadcrumb = array();
|
||||
while ($parents = taxonomy_get_parents($current->tid)) {
|
||||
|
@ -372,9 +372,9 @@ function profile_ctools_block_info($module, $delta, &$info) {
|
||||
}
|
||||
|
||||
function book_ctools_block_info($module, $delta, &$info) {
|
||||
// Hide the book navigation block which isn't as rich as what we can
|
||||
// do with context.
|
||||
$info = NULL;
|
||||
$info['title'] = t('Book navigation menu');
|
||||
$info['icon'] = 'icon_core_block_menu.png';
|
||||
$info['category'] = t('Node');
|
||||
}
|
||||
|
||||
function blog_ctools_block_info($module, $delta, &$info) {
|
||||
|
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
if (module_exists('book')) {
|
||||
/**
|
||||
* Plugins are described by creating a $plugin array which will be used
|
||||
* by the system that includes this file.
|
||||
*/
|
||||
$plugin = array(
|
||||
'single' => TRUE,
|
||||
'title' => t('Book navigation menu'),
|
||||
'icon' => '../block/icon_core_block_menu.png',
|
||||
'description' => t('The book menu belonging to the current book node.'),
|
||||
'required context' => new ctools_context_required(t('Node'), 'node'),
|
||||
'category' => t('Node'),
|
||||
);
|
||||
}
|
||||
|
||||
function ctools_node_book_menu_content_type_render($subtype, $conf, $panel_args, $context) {
|
||||
$node = isset($context->data) ? clone($context->data) : NULL;
|
||||
$block = new stdClass();
|
||||
$block->module = 'book_menu';
|
||||
|
||||
if ($conf['override_title']) {
|
||||
$block->title = t($conf['override_title_text']);
|
||||
}
|
||||
else {
|
||||
$block->title = t('Book navigation menu');
|
||||
}
|
||||
if ($node) {
|
||||
$block->delta = $node->nid;
|
||||
// TODO: the value is not available somehow?!?
|
||||
$book_block_mode = isset($conf['book_block_mode']) ? $conf['book_block_mode'] : 'book pages';
|
||||
|
||||
// Code below is taken from function book_block_view().
|
||||
$current_bid = empty($node->book['bid']) ? 0 : $node->book['bid'];
|
||||
|
||||
if ($book_block_mode === 'all pages') {
|
||||
$block->subject = t('Book navigation');
|
||||
$book_menus = array();
|
||||
$pseudo_tree = array(0 => array('below' => FALSE));
|
||||
foreach (book_get_books() as $book_id => $book) {
|
||||
if ($book['bid'] === $current_bid) {
|
||||
// If the current page is a node associated with a book, the menu
|
||||
// needs to be retrieved.
|
||||
$book_menus[$book_id] = menu_tree_output(menu_tree_all_data($node->book['menu_name'], $node->book));
|
||||
}
|
||||
else {
|
||||
// Since we know we will only display a link to the top node, there
|
||||
// is no reason to run an additional menu tree query for each book.
|
||||
$book['in_active_trail'] = FALSE;
|
||||
// Check whether user can access the book link.
|
||||
$book_node = node_load($book['nid']);
|
||||
$book['access'] = node_access('view', $book_node);
|
||||
$pseudo_tree[0]['link'] = $book;
|
||||
$book_menus[$book_id] = menu_tree_output($pseudo_tree);
|
||||
}
|
||||
}
|
||||
$book_menus['#theme'] = 'book_all_books_block';
|
||||
$block->content = $book_menus;
|
||||
}
|
||||
elseif ($current_bid) {
|
||||
// Only display this block when the user is browsing a book.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', array('title'))
|
||||
->condition('n.nid', $node->book['bid'])
|
||||
->addTag('node_access');
|
||||
$title = $select->execute()->fetchField();
|
||||
// Only show the block if the user has view access for the top-level node.
|
||||
if ($title) {
|
||||
$tree = menu_tree_all_data($node->book['menu_name'], $node->book);
|
||||
// There should only be one element at the top level.
|
||||
$data = array_shift($tree);
|
||||
// TODO: subject is not rendered
|
||||
$block->subject = theme('book_title_link', array('link' => $data['link']));
|
||||
$block->content = ($data['below']) ? menu_tree_output($data['below']) : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$block->content = t('Book navigation pager goes here.');
|
||||
$block->delta = 'unknown';
|
||||
}
|
||||
|
||||
return $block;
|
||||
}
|
||||
|
||||
function ctools_node_book_menu_content_type_admin_title($subtype, $conf, $context) {
|
||||
return t('"@s" book navigation pager', array('@s' => $context->identifier));
|
||||
}
|
||||
|
||||
function ctools_node_book_menu_content_type_edit_form($form, &$form_state) {
|
||||
// Grab block form from the book module.
|
||||
$block_form = book_block_configure($delta = '');
|
||||
// TODO: this does not work yet.
|
||||
// See TODO in: ctools_node_book_menu_content_type_render
|
||||
if (isset($form_state['input']['book_block_mode'])) {
|
||||
$block_form['book_block_mode']['#default_value'] = $form_state['input']['book_block_mode'];
|
||||
}
|
||||
$form += $block_form;
|
||||
return $form;
|
||||
}
|
@ -7,9 +7,9 @@ if (module_exists('book')) {
|
||||
*/
|
||||
$plugin = array(
|
||||
'single' => TRUE,
|
||||
'title' => t('Book navigation'),
|
||||
'icon' => 'icon_node.png',
|
||||
'description' => t('The navigation menu the book the node belongs to.'),
|
||||
'title' => t('Book navigation pager'),
|
||||
'icon' => '../block/icon_core_booknavigation.png',
|
||||
'description' => t('The navigational pager and sub pages of the current book node.'),
|
||||
'required context' => new ctools_context_required(t('Node'), 'node'),
|
||||
'category' => t('Node'),
|
||||
);
|
||||
@ -20,13 +20,13 @@ function ctools_node_book_nav_content_type_render($subtype, $conf, $panel_args,
|
||||
$block = new stdClass();
|
||||
$block->module = 'book_nav';
|
||||
|
||||
$block->title = t('Book navigation');
|
||||
$block->title = t('Book navigation pager');
|
||||
if ($node) {
|
||||
$block->content = isset($node->book) ? theme('book_navigation', array('book_link' => $node->book)) : '';
|
||||
$block->delta = $node->nid;
|
||||
}
|
||||
else {
|
||||
$block->content = t('Book navigation goes here.');
|
||||
$block->content = t('Book navigation pager goes here.');
|
||||
$block->delta = 'unknown';
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ function ctools_node_book_nav_content_type_render($subtype, $conf, $panel_args,
|
||||
}
|
||||
|
||||
function ctools_node_book_nav_content_type_admin_title($subtype, $conf, $context) {
|
||||
return t('"@s" book navigation', array('@s' => $context->identifier));
|
||||
return t('"@s" book navigation pager', array('@s' => $context->identifier));
|
||||
}
|
||||
|
||||
function ctools_node_book_nav_content_type_edit_form($form, &$form_state) {
|
||||
|
@ -6,9 +6,9 @@ version = CTOOLS_MODULE_VERSION
|
||||
dependencies[] = ctools
|
||||
dependencies[] = color
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -5,9 +5,9 @@ dependencies[] = ctools
|
||||
package = Chaos tool suite
|
||||
version = CTOOLS_MODULE_VERSION
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -5,7 +5,7 @@ class CtoolsContextKeywordsSubstitutionTestCase extends DrupalWebTestCase {
|
||||
return array(
|
||||
'name' => 'Keywords substitution',
|
||||
'description' => 'Verify that keywords are properly replaced with data.',
|
||||
'group' => 'Chaos Tools Suite',
|
||||
'group' => 'ctools',
|
||||
);
|
||||
}
|
||||
|
||||
@ -51,6 +51,30 @@ class CtoolsContextKeywordsSubstitutionTestCase extends DrupalWebTestCase {
|
||||
"%{$node->title}",
|
||||
t('Keyword after escaped and unescaped percent sign has been replaced.'),
|
||||
),
|
||||
'%%foo:bar' => array(
|
||||
"%foo:bar",
|
||||
t('Non-existant context ignored.'),
|
||||
),
|
||||
'There was about 20%-30% difference in price.' => array(
|
||||
'There was about 20%-30% difference in price.',
|
||||
t('Non-keyword percent sign left untouched.'),
|
||||
),
|
||||
'href="my%20file%2dname.pdf"' => array(
|
||||
'href="my%20file%2dname.pdf"',
|
||||
t('HTTP URL escape left untouched.'),
|
||||
),
|
||||
'href="my%a0file%fdname.pdf"' => array(
|
||||
'href="my%a0file%fdname.pdf"',
|
||||
t('HTTP URL escape (high-chars) left untouched.'),
|
||||
),
|
||||
'<a href="http://www.example.com/here%20is%20a%20pdf.pdf">Click here!</a>' => array(
|
||||
'<a href="http://www.example.com/here%20is%20a%20pdf.pdf">Click here!</a>',
|
||||
t('HTTP URL escape percent sign left untouched in HTML.'),
|
||||
),
|
||||
'SELECT * FROM {table} WHERE field = "%s"' => array(
|
||||
'SELECT * FROM {table} WHERE field = "%s"',
|
||||
t('SQL percent sign left untouched.'),
|
||||
),
|
||||
);
|
||||
foreach ($checks as $string => $expectations) {
|
||||
list($expected_result, $message) = $expectations;
|
||||
|
@ -12,7 +12,7 @@ class CtoolsCssTestCase extends DrupalWebTestCase {
|
||||
return array(
|
||||
'name' => 'CSS Tools tests',
|
||||
'description' => '...',
|
||||
'group' => 'Chaos Tools Suite',
|
||||
'group' => 'ctools',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ class CtoolsObjectCache extends DrupalWebTestCase {
|
||||
return array(
|
||||
'name' => 'Ctools CSS cache',
|
||||
'description' => 'Tests the custom CSS cache handler.',
|
||||
'group' => 'Chaos Tools Suite',
|
||||
'group' => 'ctools',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ class CtoolsPluginsGetInfoTestCase extends DrupalWebTestCase {
|
||||
return array(
|
||||
'name' => 'Get plugin info',
|
||||
'description' => 'Verify that plugin type definitions can properly set and overide values.',
|
||||
'group' => 'Chaos Tools Suite',
|
||||
'group' => 'ctools',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ class CtoolsExportCrudTestCase extends DrupalWebTestCase {
|
||||
return array(
|
||||
'name' => 'CTools export CRUD tests',
|
||||
'description' => 'Test the CRUD functionality for the ctools export system.',
|
||||
'group' => 'Chaos Tools Suite',
|
||||
'group' => 'ctools',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,9 @@ hidden = TRUE
|
||||
|
||||
files[] = ctools_export.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -12,9 +12,9 @@ files[] = math_expression.test
|
||||
files[] = math_expression_stack.test
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -13,7 +13,7 @@ class CtoolsMathExpressionTestCase extends DrupalWebTestCase {
|
||||
return array(
|
||||
'name' => 'CTools math expression tests',
|
||||
'description' => 'Test the math expression library of ctools.',
|
||||
'group' => 'Chaos Tools Suite',
|
||||
'group' => 'ctools',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ class CtoolsMathExpressionStackTestCase extends DrupalWebTestCase {
|
||||
return array(
|
||||
'name' => 'CTools math expression stack tests',
|
||||
'description' => 'Test the stack class of the math expression library.',
|
||||
'group' => 'Chaos Tools Suite',
|
||||
'group' => 'ctools',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ class CtoolsObjectCache extends DrupalWebTestCase {
|
||||
return array(
|
||||
'name' => 'Ctools object cache storage',
|
||||
'description' => 'Verify that objects are written, readable and lockable.',
|
||||
'group' => 'Chaos Tools Suite',
|
||||
'group' => 'ctools',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -10,9 +10,9 @@ files[] = plugins/views/views_content_plugin_display_ctools_context.inc
|
||||
files[] = plugins/views/views_content_plugin_display_panel_pane.inc
|
||||
files[] = plugins/views/views_content_plugin_style_ctools_context.inc
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-1.11"
|
||||
; Information added by Drupal.org packaging script on 2016-11-22
|
||||
version = "7.x-1.12"
|
||||
core = "7.x"
|
||||
project = "ctools"
|
||||
datestamp = "1476581654"
|
||||
datestamp = "1479787162"
|
||||
|
||||
|
@ -28,6 +28,7 @@ function date_field_formatter_info() {
|
||||
'settings' => array(
|
||||
'interval' => 2,
|
||||
'interval_display' => 'time ago',
|
||||
'use_end_date' => false,
|
||||
),
|
||||
),
|
||||
'date_plain' => array(
|
||||
@ -207,7 +208,7 @@ function date_field_formatter_view($entity_type, $entity, $field, $instance, $la
|
||||
$variables['item'] = $item;
|
||||
$variables['dates'] = date_formatter_process($formatter, $entity_type, $entity, $field, $instance, $langcode, $item, $display);
|
||||
$variables['attributes'] = !empty($rdf_mapping) ? rdf_rdfa_attributes($rdf_mapping, $item['value']) : array();
|
||||
$variables['show_remaining_days'] = $display['settings']['show_remaining_days'];
|
||||
$variables['show_remaining_days'] = isset($display['settings']['show_remaining_days']) ? $display['settings']['show_remaining_days'] : FALSE;
|
||||
$output = theme('date_display_combination', $variables);
|
||||
if (!empty($output)) {
|
||||
$element[$delta] = array('#markup' => $output);
|
||||
@ -322,7 +323,7 @@ function date_field_widget_info() {
|
||||
}
|
||||
|
||||
// The date text widget should use an increment of 1.
|
||||
$info['date_text']['increment'] = 1;
|
||||
$info['date_text']['settings']['increment'] = 1;
|
||||
|
||||
return $info;
|
||||
}
|
||||
@ -462,6 +463,14 @@ function date_field_instance_settings_form($field, $instance) {
|
||||
return _date_field_instance_settings_form($field, $instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form validation handler for _date_field_instance_settings_form().
|
||||
*/
|
||||
function date_field_instance_settings_form_validate(&$form, &$form_state) {
|
||||
module_load_include('inc', 'date', 'date_admin');
|
||||
return _date_field_instance_settings_form_validate($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_settings_form().
|
||||
*/
|
||||
@ -470,6 +479,14 @@ function date_field_widget_settings_form($field, $instance) {
|
||||
return _date_field_widget_settings_form($field, $instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form validation handler for _date_field_widget_settings_form().
|
||||
*/
|
||||
function date_field_widget_settings_form_validate(&$form, &$form_state) {
|
||||
module_load_include('inc', 'date', 'date_admin');
|
||||
return _date_field_widget_settings_form_validate($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_settings_form().
|
||||
*/
|
||||
@ -478,6 +495,14 @@ function date_field_settings_form($field, $instance, $has_data) {
|
||||
return _date_field_settings_form($field, $instance, $has_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form validation handler for _date_field_settings_form().
|
||||
*/
|
||||
function date_field_settings_validate(&$form, &$form_state) {
|
||||
module_load_include('inc', 'date', 'date_admin');
|
||||
return _date_field_settings_validate($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_content_migrate_field_alter().
|
||||
*
|
||||
|
@ -13,10 +13,11 @@ files[] = tests/date_validation.test
|
||||
files[] = tests/date_timezone.test
|
||||
files[] = tests/date_views_pager.test
|
||||
files[] = tests/date_views_popup.test
|
||||
files[] = tests/date_form.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-09-08
|
||||
version = "7.x-2.9"
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1441727353"
|
||||
datestamp = "1491562090"
|
||||
|
||||
|
@ -204,3 +204,11 @@ function date_update_7004() {
|
||||
field_cache_clear();
|
||||
drupal_set_message(t('Date text widgets have been updated to use an increment of 1.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Revisited: Date text widgets should always use an increment of 1.
|
||||
*/
|
||||
function date_update_7005() {
|
||||
// @see https://www.drupal.org/node/1355256
|
||||
date_update_7004();
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Support for migration into Date fields.
|
||||
*/
|
||||
|
||||
if (!class_exists('MigrateFieldHandler')) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_migrate_api().
|
||||
*/
|
||||
|
@ -443,7 +443,12 @@ function date_formatter_format($formatter, $settings, $granularity = array(), $l
|
||||
return 'date_plain';
|
||||
|
||||
default:
|
||||
$format = date_format_type_format($format_type, $langcode);
|
||||
if ($format_type == 'custom') {
|
||||
$format = $settings['custom_date_format'];
|
||||
}
|
||||
else {
|
||||
$format = date_format_type_format($format_type, $langcode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -349,10 +349,10 @@ function theme_date_display_range($variables) {
|
||||
}
|
||||
|
||||
// Wrap the result with the attributes.
|
||||
$output = '<div class="date-display-range">' . t('!start-date to !end-date', array(
|
||||
$output = '<span class="date-display-range">' . t('!start-date to !end-date', array(
|
||||
'!start-date' => $start_date,
|
||||
'!end-date' => $end_date,
|
||||
)) . '</div>';
|
||||
)) . '</span>';
|
||||
|
||||
// Add remaining message and return.
|
||||
return $output . $show_remaining_days;
|
||||
@ -378,6 +378,8 @@ function theme_date_display_interval($variables) {
|
||||
'end_date' => $dates['value2']['local']['object'],
|
||||
'interval' => $options['interval'],
|
||||
'interval_display' => $options['interval_display'],
|
||||
'use_end_date' => !empty($options['use_end_date']) ?
|
||||
$options['use_end_date'] : FALSE,
|
||||
);
|
||||
|
||||
if ($return = theme('date_time_ago', $time_ago_vars)) {
|
||||
@ -398,9 +400,9 @@ function theme_date_combo($variables) {
|
||||
|
||||
// Group start/end items together in fieldset.
|
||||
$fieldset = array(
|
||||
'#title' => field_filter_xss(t($element['#title'])) . ' ' . ($element['#delta'] > 0 ? intval($element['#delta'] + 1) : ''),
|
||||
'#title' => field_filter_xss(t($element['#title'])) . ($element['#delta'] > 0 ? ' ' . intval($element['#delta'] + 1) : ''),
|
||||
'#value' => '',
|
||||
'#description' => !empty($element['#fieldset_description']) ? $element['#fieldset_description'] : '',
|
||||
'#description' => !empty($element['#description']) ? $element['#description'] : '',
|
||||
'#attributes' => array('class' => array('date-combo')),
|
||||
'#children' => $element['#children'],
|
||||
);
|
||||
|
@ -14,15 +14,24 @@ function date_default_formatter_settings_form($field, $instance, $view_mode, $fo
|
||||
$formatter = $display['type'];
|
||||
$form = array();
|
||||
|
||||
$date_formats = date_format_type_options();
|
||||
$form['format_type'] = array(
|
||||
'#title' => t('Choose how users view dates and times:'),
|
||||
'#type' => 'select',
|
||||
'#options' => date_format_type_options(),
|
||||
'#options' => $date_formats + array('custom' => t('Custom')),
|
||||
'#default_value' => $settings['format_type'],
|
||||
'#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'))),
|
||||
'#weight' => 0,
|
||||
);
|
||||
|
||||
$form['custom_date_format'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Custom date format'),
|
||||
'#description' => t('If "Custom", see the <a href="@url" target="_blank">PHP manual</a> for date formats. Otherwise, enter the number of different time units to display, which defaults to 2.', array('@url' => 'http://php.net/manual/function.date.php')),
|
||||
'#default_value' => isset($settings['custom_date_format']) ? $settings['custom_date_format'] : '',
|
||||
'#dependency' => array('edit-options-settings-format-type' => array('custom')),
|
||||
);
|
||||
|
||||
$form['fromto'] = array(
|
||||
'#title' => t('Display:'),
|
||||
'#type' => 'select',
|
||||
@ -116,6 +125,14 @@ function date_interval_formatter_settings_form($field, $instance, $view_mode, $f
|
||||
'#default_value' => $settings['interval_display'],
|
||||
'#weight' => 0,
|
||||
);
|
||||
if (!empty($field['settings']['todate'])) {
|
||||
$form['use_end_date'] = array(
|
||||
'#title' => t('Use End date'),
|
||||
'#description' => 'Use the End date, instead of the start date',
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => $settings['use_end_date'],
|
||||
);
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
@ -186,7 +203,9 @@ function date_interval_formatter_settings_summary($field, $instance, $view_mode)
|
||||
$display = $instance['display'][$view_mode];
|
||||
$settings = $display['settings'];
|
||||
$formatter = $display['type'];
|
||||
$summary[] = t('Display time ago, showing @interval units.', array('@interval' => $settings['interval']));
|
||||
$field = ($settings['use_end_date'] == 1) ? 'End' : 'Start';
|
||||
$summary[] = t('Display time ago, showing @interval units. Using @field Date',
|
||||
array('@interval' => $settings['interval'], '@field' => $field));
|
||||
|
||||
return $summary;
|
||||
}
|
||||
@ -273,7 +292,7 @@ function _date_field_instance_settings_form($field, $instance) {
|
||||
/**
|
||||
* Form validation handler for _date_field_instance_settings_form().
|
||||
*/
|
||||
function date_field_instance_settings_form_validate(&$form, &$form_state) {
|
||||
function _date_field_instance_settings_form_validate(&$form, &$form_state) {
|
||||
$settings = $form_state['values']['instance']['settings'];
|
||||
|
||||
if ($settings['default_value'] == 'strtotime') {
|
||||
@ -459,7 +478,7 @@ function _date_field_widget_settings_form($field, $instance) {
|
||||
/**
|
||||
* Form validation handler for _date_field_widget_settings_form().
|
||||
*/
|
||||
function date_field_widget_settings_form_validate(&$form, &$form_state) {
|
||||
function _date_field_widget_settings_form_validate(&$form, &$form_state) {
|
||||
// The widget settings are in the wrong place in the form because of #tree on
|
||||
// the top level.
|
||||
$settings = $form_state['values']['instance']['widget']['settings'];
|
||||
@ -561,7 +580,7 @@ function _date_field_settings_form($field, $instance, $has_data) {
|
||||
$form['cache_enabled'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Cache dates'),
|
||||
'#description' => t('Date objects can be created and cached as date fields are loaded rather than when they are displayed to improve performance.'),
|
||||
'#description' => t('Date objects can be created and cached as date fields are loaded, rather than when they are displayed, to improve performance.'),
|
||||
'#default_value' => !empty($settings['cache_enabled']),
|
||||
'#weight' => 10,
|
||||
);
|
||||
@ -594,7 +613,7 @@ function _date_field_settings_form($field, $instance, $has_data) {
|
||||
/**
|
||||
* Form validation handler for _date_field_settings_form().
|
||||
*/
|
||||
function date_field_settings_validate(&$form, &$form_state) {
|
||||
function _date_field_settings_validate(&$form, &$form_state) {
|
||||
$field = &$form_state['values']['field'];
|
||||
|
||||
if ($field['settings']['tz_handling'] == 'none') {
|
||||
|
@ -5,9 +5,9 @@ dependencies[] = date
|
||||
package = Date/Time
|
||||
core = 7.x
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-09-08
|
||||
version = "7.x-2.9"
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1441727353"
|
||||
datestamp = "1491562090"
|
||||
|
||||
|
@ -9,9 +9,9 @@ stylesheets[all][] = date.css
|
||||
files[] = date_api.module
|
||||
files[] = date_api_sql.inc
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-09-08
|
||||
version = "7.x-2.9"
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1441727353"
|
||||
datestamp = "1491562090"
|
||||
|
||||
|
@ -1833,9 +1833,10 @@ function date_format_interval($date, $granularity = 2, $display_ago = TRUE) {
|
||||
/**
|
||||
* A date object for the current time.
|
||||
*
|
||||
* @param object $timezone
|
||||
* (optional) Optionally force time to a specific timezone, defaults to user
|
||||
* timezone, if set, otherwise site timezone. Defaults to NULL.
|
||||
* @param object|string|null $timezone
|
||||
* (optional) PHP DateTimeZone object, string or NULL allowed. Optionally
|
||||
* force time to a specific timezone, defaults to user timezone, if set,
|
||||
* otherwise site timezone. Defaults to NULL.
|
||||
*
|
||||
* @param bool $reset
|
||||
* (optional) Static cache reset.
|
||||
@ -1844,11 +1845,16 @@ function date_format_interval($date, $granularity = 2, $display_ago = TRUE) {
|
||||
* The current time as a date object.
|
||||
*/
|
||||
function date_now($timezone = NULL, $reset = FALSE) {
|
||||
if ($reset) {
|
||||
drupal_static_reset(__FUNCTION__ . $timezone);
|
||||
$static_var = __FUNCTION__ . $timezone;
|
||||
if ($timezone instanceof DateTimeZone) {
|
||||
$static_var = __FUNCTION__ . $timezone->getName();
|
||||
}
|
||||
|
||||
$now = &drupal_static(__FUNCTION__ . $timezone);
|
||||
if ($reset) {
|
||||
drupal_static_reset($static_var);
|
||||
}
|
||||
|
||||
$now = &drupal_static($static_var);
|
||||
|
||||
if (!isset($now)) {
|
||||
$now = new DateObject('now', $timezone);
|
||||
@ -1920,7 +1926,12 @@ function date_days_in_month($year, $month) {
|
||||
// Pick a day in the middle of the month to avoid timezone shifts.
|
||||
$datetime = date_pad($year, 4) . '-' . date_pad($month) . '-15 00:00:00';
|
||||
$date = new DateObject($datetime);
|
||||
return $date->format('t');
|
||||
if ($date->errors) {
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
return $date->format('t');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2075,6 +2086,9 @@ function date_iso_week_range($week, $year) {
|
||||
date_timezone_set($min_date, date_default_timezone_object());
|
||||
|
||||
// Find the first day of the first ISO week in the year.
|
||||
// If it's already a Monday, date_modify won't add a Monday,
|
||||
// it will remain the same day. So add a Sunday first, then a Monday.
|
||||
date_modify($min_date, '+1 Sunday');
|
||||
date_modify($min_date, '+1 Monday');
|
||||
|
||||
// Jump ahead to the desired week for the beginning of the week range.
|
||||
|
@ -111,7 +111,7 @@ function date_default_date($element) {
|
||||
$format = DATE_FORMAT_DATETIME;
|
||||
|
||||
// The text and popup widgets might return less than a full datetime string.
|
||||
if (strlen($element['#default_value']) < 19) {
|
||||
if (is_string($element['#default_value']) && strlen($element['#default_value']) < 19) {
|
||||
switch (strlen($element['#default_value'])) {
|
||||
case 16:
|
||||
$format = 'Y-m-d H:i';
|
||||
@ -319,7 +319,7 @@ function date_text_element_process($element, &$form_state, $form) {
|
||||
|
||||
$element['#tree'] = TRUE;
|
||||
$element['#theme_wrappers'] = array('date_text');
|
||||
$element['date']['#value'] = $element['#value']['date'];
|
||||
$element['date']['#value'] = isset($element['#value']['date']) ? $element['#value']['date'] : '';
|
||||
$element['date']['#type'] = 'textfield';
|
||||
$element['date']['#weight'] = !empty($element['date']['#weight']) ? $element['date']['#weight'] : $element['#weight'];
|
||||
$element['date']['#attributes'] = array('class' => isset($element['#attributes']['class']) ? $element['#attributes']['class'] += array('date-date') : array('date-date'));
|
||||
|
@ -194,6 +194,7 @@ function theme_date_calendar_day($variables) {
|
||||
function theme_date_time_ago($variables) {
|
||||
$start_date = $variables['start_date'];
|
||||
$end_date = $variables['end_date'];
|
||||
$use_end_date = isset($variables['use_end_date']) ? $variables['use_end_date'] : false;
|
||||
$interval = !empty($variables['interval']) ? $variables['interval'] : 2;
|
||||
$display = isset($variables['interval_display']) ? $variables['interval_display'] : 'time ago';
|
||||
|
||||
@ -202,12 +203,20 @@ function theme_date_time_ago($variables) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We use the end date only when the option is checked.
|
||||
if ($use_end_date){
|
||||
$date = date_format($end_date, DATE_FORMAT_UNIX);
|
||||
}
|
||||
else {
|
||||
$date = date_format($start_date, DATE_FORMAT_UNIX);
|
||||
}
|
||||
|
||||
// Time to compare dates to.
|
||||
|
||||
$now = date_format(date_now(), DATE_FORMAT_UNIX);
|
||||
$start = date_format($start_date, DATE_FORMAT_UNIX);
|
||||
|
||||
// Will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence).
|
||||
$time_diff = $now - $start;
|
||||
$time_diff = $now - $date;
|
||||
|
||||
// Uses the same options used by Views format_interval.
|
||||
switch ($display) {
|
||||
|
@ -8,9 +8,9 @@ dependencies[] = context
|
||||
|
||||
files[] = date_context.module
|
||||
files[] = plugins/date_context_date_condition.inc
|
||||
; Information added by Drupal.org packaging script on 2015-09-08
|
||||
version = "7.x-2.9"
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1441727353"
|
||||
datestamp = "1491562090"
|
||||
|
||||
|
@ -74,7 +74,7 @@ function date_field_widget_form(&$form, &$form_state, $field, $instance, $langco
|
||||
// The repeating values will be re-generated when the repeat widget form is validated.
|
||||
// At this point we can't tell if this form element is going to be hidden by #access, and we're going to
|
||||
// lose all but the first value by doing this, so store the original values in case we need to replace them later.
|
||||
if (!empty($field['settings']['repeat'])) {
|
||||
if (!empty($field['settings']['repeat']) && module_exists('date_repeat_field')) {
|
||||
if ($delta == 0) {
|
||||
$form['#after_build'][] = 'date_repeat_after_build';
|
||||
$form_state['storage']['repeat_fields'][$field_name] = array_merge($form['#parents'], array($field_name));
|
||||
@ -337,8 +337,11 @@ function date_combo_element_process($element, &$form_state, $form) {
|
||||
'#date_label_position' => $instance['widget']['settings']['label_position'],
|
||||
);
|
||||
|
||||
$description = !empty($element['#description']) ? t($element['#description']) : '';
|
||||
unset($element['#description']);
|
||||
// Date repeat is a multiple value field. So the description is removed from
|
||||
// the single element earlier. Let's get it back.
|
||||
if (isset($element['show_repeat_settings']) && !empty($element['value']['#instance']['description'])) {
|
||||
$element['#description'] = $element['value']['#instance']['description'];
|
||||
}
|
||||
|
||||
// Give this element the right type, using a Date API
|
||||
// or a Date Popup element type.
|
||||
@ -383,8 +386,7 @@ function date_combo_element_process($element, &$form_state, $form) {
|
||||
$element[$to_field]['#prefix'] = '';
|
||||
// Users with JS enabled will never see initially blank values for the end
|
||||
// date (see Drupal.date.EndDateHandler()), so hide the message for them.
|
||||
$description .= '<span class="js-hide"> ' . t("Empty 'End date' values will use the 'Start date' values.") . '</span>';
|
||||
$element['#fieldset_description'] = $description;
|
||||
$element['#description'] .= '<span class="js-hide"> ' . t("Empty 'End date' values will use the 'Start date' values.") . '</span>';
|
||||
if ($field['settings']['todate'] == 'optional') {
|
||||
$element[$to_field]['#states'] = array(
|
||||
'visible' => array(
|
||||
@ -395,9 +397,6 @@ function date_combo_element_process($element, &$form_state, $form) {
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$element[$from_field]['#description'] = $description;
|
||||
}
|
||||
|
||||
// Create label for error messages that make sense in multiple values
|
||||
// and when the title field is left blank.
|
||||
@ -474,6 +473,12 @@ function date_combo_validate($element, &$form_state) {
|
||||
$form_values = drupal_array_get_nested_value($form_state['values'], $element['#field_parents']);
|
||||
$form_input = drupal_array_get_nested_value($form_state['input'], $element['#field_parents']);
|
||||
|
||||
// Programmatically calling drupal_submit_form() does not always add the date
|
||||
// combo to $form_state['input'].
|
||||
if (empty($form_input[$field_name]) && !empty($form_values[$field_name])) {
|
||||
form_set_value($element, $element['#date_items'], $form_state);
|
||||
return;
|
||||
}
|
||||
// If the whole field is empty and that's OK, stop now.
|
||||
if (empty($form_input[$field_name]) && !$element['#required']) {
|
||||
return;
|
||||
@ -546,11 +551,7 @@ function date_combo_validate($element, &$form_state) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Don't look for further errors if errors are already flagged
|
||||
// because otherwise we'll show errors on the nested elements
|
||||
// more than once.
|
||||
elseif (!form_get_errors()) {
|
||||
|
||||
else {
|
||||
$timezone = !empty($item[$tz_field]) ? $item[$tz_field] : $element['#date_timezone'];
|
||||
$timezone_db = date_get_timezone_db($field['settings']['tz_handling']);
|
||||
$element[$from_field]['#date_timezone'] = $timezone;
|
||||
@ -625,7 +626,10 @@ function date_combo_validate($element, &$form_state) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($errors)) {
|
||||
// Don't show further errors if errors are already flagged
|
||||
// because otherwise we'll show errors on the nested elements
|
||||
// more than once.
|
||||
if (!form_get_errors() && !empty($errors)) {
|
||||
if ($field['cardinality']) {
|
||||
form_error($element, t('There are errors in @field_name value #@delta:', array('@field_name' => $instance['label'], '@delta' => $delta + 1)) . theme('item_list', array('items' => $errors)));
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ core = 7.x
|
||||
package = Date/Time
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-09-08
|
||||
version = "7.x-2.9"
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1441727353"
|
||||
datestamp = "1491562090"
|
||||
|
||||
|
@ -20,9 +20,9 @@ package = "Features"
|
||||
project = "date_migrate_example"
|
||||
version = "7.x-2.0"
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-09-08
|
||||
version = "7.x-2.9"
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1441727353"
|
||||
datestamp = "1491562090"
|
||||
|
||||
|
@ -7,9 +7,9 @@ configure = admin/config/date/date_popup
|
||||
|
||||
stylesheets[all][] = themes/datepicker.1.7.css
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-09-08
|
||||
version = "7.x-2.9"
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1441727353"
|
||||
datestamp = "1491562090"
|
||||
|
||||
|
@ -14,6 +14,14 @@
|
||||
$(this).click(function(){
|
||||
$(this).focus();
|
||||
});
|
||||
if (datePopup.settings.syncEndDate) {
|
||||
$('.start-date-wrapper').each(function(){
|
||||
var start_date_wrapper = this;
|
||||
$(this).find('input:eq(0)').change(function(){
|
||||
$(start_date_wrapper).next('.end-date-wrapper').find('input:eq(0)').val($(this).val());
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case 'timeEntry':
|
||||
|
@ -394,6 +394,10 @@ function date_popup_process_date_part(&$element) {
|
||||
'fromTo' => isset($fromto),
|
||||
);
|
||||
|
||||
if (!empty($element['#instance'])) {
|
||||
$settings['syncEndDate'] = $element['#instance']['settings']['default_value2'] == 'sync';
|
||||
}
|
||||
|
||||
// Create a unique id for each set of custom settings.
|
||||
$id = date_popup_js_settings_id($element['#id'], 'datepicker', $settings);
|
||||
|
||||
@ -474,10 +478,11 @@ function date_popup_process_time_part(&$element) {
|
||||
$grans = array('hour', 'minute', 'second');
|
||||
$time_granularity = array_intersect($granularity, $grans);
|
||||
$format = date_popup_format_to_popup_time(date_limit_format($element['#date_format'], $time_granularity), 'wvega');
|
||||
$default_value = isset($element['#default_value']) ? $element['#default_value'] : '';
|
||||
// The first value in the dropdown list should be the same as the element
|
||||
// default_value, but it needs to be in JS format (i.e. milliseconds since
|
||||
// the epoch).
|
||||
$start_time = new DateObject($element['#default_value'], $element['#date_timezone'], DATE_FORMAT_DATETIME);
|
||||
$start_time = new DateObject($default_value, $element['#date_timezone'], DATE_FORMAT_DATETIME);
|
||||
date_increment_round($start_time, $element['#date_increment']);
|
||||
$start_time = $start_time->format(DATE_FORMAT_UNIX) * 1000;
|
||||
$settings = array(
|
||||
@ -580,7 +585,7 @@ function date_popup_validate($element, &$form_state) {
|
||||
// If something was input but there is no date, the date is invalid.
|
||||
// If the field is empty and required, set error message and return.
|
||||
$error_field = implode('][', $element['#parents']);
|
||||
if (empty($date) || !empty($date->errors)) {
|
||||
if ((empty($element['#value']['date']) && empty($element['#value']['time'])) || !empty($date->errors)) {
|
||||
if (is_object($date) && !empty($date->errors)) {
|
||||
$message = t('The value input for field %field is invalid:', array('%field' => $label));
|
||||
$message .= '<br />' . implode('<br />', $date->errors);
|
||||
@ -613,7 +618,9 @@ function date_popup_validate($element, &$form_state) {
|
||||
*/
|
||||
function date_popup_input_date($element, $input, $auto_complete = FALSE) {
|
||||
if (empty($input) || !is_array($input) || !array_key_exists('date', $input) || empty($input['date'])) {
|
||||
return NULL;
|
||||
//check if there is no time associated in the input variable. This is the exception scenario where the user has entered only time and not date.
|
||||
if(empty($input['time']))
|
||||
return NULL;
|
||||
}
|
||||
date_popup_add();
|
||||
$granularity = date_format_order($element['#date_format']);
|
||||
@ -622,9 +629,14 @@ function date_popup_input_date($element, $input, $auto_complete = FALSE) {
|
||||
|
||||
$format = date_popup_date_format($element);
|
||||
$format .= $has_time ? ' ' . date_popup_time_format($element) : '';
|
||||
$datetime = trim($input['date']);
|
||||
//check if date is empty, if yes, then leave it blank.
|
||||
$datetime = !empty($input['date']) ? trim($input['date']) : '';
|
||||
$datetime .= $has_time ? ' ' . trim($input['time']) : '';
|
||||
$date = new DateObject($datetime, $element['#date_timezone'], $format);
|
||||
//if the variable is time only then set TimeOnly to TRUE
|
||||
if(empty($input['date']) && !empty($input['time']) ){
|
||||
$date->timeOnly = 'TRUE';
|
||||
}
|
||||
if (is_object($date)) {
|
||||
$date->limitGranularity($granularity);
|
||||
if ($date->validGranularity($granularity, $flexible)) {
|
||||
@ -800,6 +812,14 @@ function theme_date_popup($vars) {
|
||||
return '<div ' . drupal_attributes($attributes) . '>' . theme('form_element', $element) . '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_date_field_instance_settings_form_alter().
|
||||
*/
|
||||
function date_popup_date_field_instance_settings_form_alter(&$form, $context) {
|
||||
// Add an extra option to sync the end date with the start date.
|
||||
$form['default_value2']['#options']['sync'] = t('Sync with start date');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
|
@ -7,9 +7,9 @@ php = 5.2
|
||||
files[] = tests/date_repeat.test
|
||||
files[] = tests/date_repeat_form.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-09-08
|
||||
version = "7.x-2.9"
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1441727353"
|
||||
datestamp = "1491562090"
|
||||
|
||||
|
@ -25,7 +25,7 @@ class DateRepeatFormTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Create and log in our privileged user.
|
||||
$this->privileged_user = $this->drupalCreateUser(array(
|
||||
'administer content types', 'administer nodes', 'bypass node access', 'view date repeats'
|
||||
'administer content types', 'administer nodes', 'bypass node access', 'view date repeats', 'administer fields'
|
||||
));
|
||||
$this->drupalLogin($this->privileged_user);
|
||||
|
||||
|
@ -7,9 +7,9 @@ stylesheets[all][] = date_repeat_field.css
|
||||
package = Date/Time
|
||||
core = 7.x
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-09-08
|
||||
version = "7.x-2.9"
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1441727353"
|
||||
datestamp = "1491562090"
|
||||
|
||||
|
@ -6,9 +6,9 @@ core = 7.x
|
||||
configure = admin/config/date/tools
|
||||
files[] = tests/date_tools.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-09-08
|
||||
version = "7.x-2.9"
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1441727353"
|
||||
datestamp = "1491562090"
|
||||
|
||||
|
@ -28,7 +28,7 @@ class DateToolsTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Create and log in our privileged user.
|
||||
$this->privileged_user = $this->drupalCreateUser(
|
||||
array('administer content types', 'administer nodes', 'bypass node access', 'administer date tools')
|
||||
array('administer content types', 'administer nodes', 'bypass node access', 'administer date tools', 'administer fields')
|
||||
);
|
||||
$this->drupalLogin($this->privileged_user);
|
||||
|
||||
|
@ -12,9 +12,9 @@ files[] = includes/date_views_filter_handler_simple.inc
|
||||
files[] = includes/date_views.views.inc
|
||||
files[] = includes/date_views_plugin_pager.inc
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-09-08
|
||||
version = "7.x-2.9"
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1441727353"
|
||||
datestamp = "1491562090"
|
||||
|
||||
|
@ -42,6 +42,32 @@ class date_views_filter_handler extends date_views_filter_handler_simple {
|
||||
$this->date_combine_conditions('op_contains');
|
||||
}
|
||||
|
||||
function op_empty($field) {
|
||||
$this->get_query_fields();
|
||||
if (empty($this->query_fields)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add each condition to the custom filter group.
|
||||
foreach ((array) $this->query_fields as $query_field) {
|
||||
$field = $query_field['field'];
|
||||
$this->date_handler = $query_field['date_handler'];
|
||||
|
||||
// Respect relationships when determining the table alias.
|
||||
if ($field['table_name'] != $this->table || !empty($this->relationship)) {
|
||||
$this->related_table_alias = $this->query->ensure_table($field['table_name'], $this->relationship);
|
||||
}
|
||||
else {
|
||||
$this->related_table_alias = NULL;
|
||||
}
|
||||
|
||||
$table_alias = !empty($this->related_table_alias) ? $this->related_table_alias : $field['table_name'];
|
||||
$field_name = $table_alias . '.' . $field['field_name'];
|
||||
|
||||
parent::op_empty($field_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines multiple date WHERE expressions into a single WHERE expression.
|
||||
*
|
||||
@ -67,7 +93,7 @@ class date_views_filter_handler extends date_views_filter_handler_simple {
|
||||
$this->related_table_alias = $this->query->ensure_table($field['table_name'], $this->relationship);
|
||||
}
|
||||
else {
|
||||
$this->related_table_alias = null;
|
||||
$this->related_table_alias = NULL;
|
||||
}
|
||||
$table_alias = !empty($this->related_table_alias) ? $this->related_table_alias : $field['table_name'];
|
||||
$field_name = $table_alias . '.' . $field['field_name'];
|
||||
|
@ -281,7 +281,7 @@ class date_views_plugin_pager extends views_plugin_pager {
|
||||
else {
|
||||
$this->view->date_info->prev_date = clone($argument->min_date);
|
||||
date_modify($this->view->date_info->prev_date, '-1 ' . $argument->date_handler->granularity);
|
||||
$this->view->date_info->next_date = clone($argument->max_date);
|
||||
$this->view->date_info->next_date = clone($argument->min_date);
|
||||
date_modify($this->view->date_info->next_date, '+1 ' . $argument->date_handler->granularity);
|
||||
}
|
||||
// Write the date_info properties that depend on the current value.
|
||||
|
@ -77,7 +77,7 @@ function template_preprocess_date_views_pager(&$vars) {
|
||||
switch ($granularity) {
|
||||
case 'week':
|
||||
$prev_week = date_week(date_format($prev_date, 'Y-m-d'));
|
||||
$prev_arg = date_format($prev_date, 'Y-\W') . date_pad($prev_week);
|
||||
$prev_arg = date_format($prev_date, 'o-\W') . date_pad($prev_week);
|
||||
break;
|
||||
default:
|
||||
$prev_arg = date_format($prev_date, $format[$granularity]);
|
||||
@ -90,7 +90,7 @@ function template_preprocess_date_views_pager(&$vars) {
|
||||
switch ($granularity) {
|
||||
case 'week':
|
||||
$next_week = date_week(date_format($next_date, 'Y-m-d'));
|
||||
$next_arg = date_format($next_date, 'Y-\W') . date_pad($next_week);
|
||||
$next_arg = date_format($next_date, 'o-\W') . date_pad($next_week);
|
||||
break;
|
||||
default:
|
||||
$next_arg = date_format($next_date, $format[$granularity]);
|
||||
|
@ -393,7 +393,7 @@ class DateAPITestCase extends DrupalWebTestCase {
|
||||
$input = '23 abc 2012';
|
||||
$timezone = NULL;
|
||||
$format = 'd M Y';
|
||||
$date = new dateObject($input, $timezone, $format);
|
||||
$date = @new dateObject($input, $timezone, $format);
|
||||
$this->assertNotEqual(count($date->errors), 0, '23 abc 2012 should be an invalid date');
|
||||
|
||||
// Test Granularity.
|
||||
|
@ -16,7 +16,7 @@ abstract class DateFieldBasic extends DrupalWebTestCase {
|
||||
|
||||
// Create and log in our privileged user.
|
||||
$this->privileged_user = $this->drupalCreateUser(
|
||||
array('administer content types', 'administer nodes', 'bypass node access', 'administer date tools')
|
||||
array('administer content types', 'administer nodes', 'bypass node access', 'administer date tools', 'administer fields')
|
||||
);
|
||||
$this->drupalLogin($this->privileged_user);
|
||||
|
||||
|
30
sites/all/modules/contrib/fields/date/tests/date_form.test
Normal file
30
sites/all/modules/contrib/fields/date/tests/date_form.test
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains form specific date element test cases.
|
||||
*/
|
||||
|
||||
class DateFormTestCase extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => t('Date Form test'),
|
||||
'description' => t('Test Date form functions.') ,
|
||||
'group' => t('Date'),
|
||||
);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
// Load the date_api module.
|
||||
parent::setUp('date_test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests rendering of a date element in a form.
|
||||
*/
|
||||
public function testDateForm() {
|
||||
$this->drupalGet('date-test/form');
|
||||
}
|
||||
|
||||
}
|
@ -18,6 +18,7 @@ class DateMigrateExampleUnitTest extends DrupalWebTestCase {
|
||||
'name' => 'Date Migration',
|
||||
'description' => 'Test migration into date fields',
|
||||
'group' => 'Date',
|
||||
'dependencies' => array('migrate', 'features'),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,14 @@
|
||||
name = "Date module tests"
|
||||
description = "Support module for date related testing."
|
||||
package = Date/Time
|
||||
version = VERSION
|
||||
core = 7.x
|
||||
hidden = TRUE
|
||||
dependencies[] = date
|
||||
|
||||
; Information added by Drupal.org packaging script on 2017-04-07
|
||||
version = "7.x-2.10"
|
||||
core = "7.x"
|
||||
project = "date"
|
||||
datestamp = "1491562090"
|
||||
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains date test implementations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function date_test_menu() {
|
||||
$items['date-test/form'] = array(
|
||||
'title' => 'Test form with date element',
|
||||
'description' => "Form with date element to make form related tests",
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('date_test_sample_form'),
|
||||
'access arguments' => array('access content'),
|
||||
'type' => MENU_CALLBACK,
|
||||
);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form callback. Generates a test form with date elements.
|
||||
*/
|
||||
function date_test_sample_form($form, &$form_state) {
|
||||
$form['date_test_select'] = array(
|
||||
'#type' => 'date_select',
|
||||
'#title' => t('Sample from'),
|
||||
'#date_format' => 'H:i:s a',
|
||||
'#default_value' => array(
|
||||
'hour' => 7,
|
||||
'minute' => 0,
|
||||
'second' => 0,
|
||||
'ampm' => 'am'
|
||||
),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
@ -16,6 +16,16 @@ class DateTimezoneTestCase extends DateFieldBasic {
|
||||
);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
// Set the timezone explicitly. Otherwise the site's default timezone is
|
||||
// used, which defaults to the server timezone when installing Drupal. This
|
||||
// depends on the environment and is therefore uncertain.
|
||||
// The Australia/Sydney timezone is chosen so all tests are run using an
|
||||
// edge case scenario (UTC+10 and DST).
|
||||
variable_set('date_default_timezone', 'Australia/Sydney');
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo.
|
||||
*/
|
||||
@ -23,7 +33,7 @@ class DateTimezoneTestCase extends DateFieldBasic {
|
||||
// Create a date fields with combinations of various timezone handling and
|
||||
// granularity.
|
||||
foreach (array('date', 'datestamp', 'datetime') as $field_type) {
|
||||
foreach (array('site', 'none', 'date', 'user', 'utc') as $tz_handling) {
|
||||
foreach (array('site', 'none', 'date', 'user', 'utc', 'Europe/Dublin') as $tz_handling) {
|
||||
foreach (array('year', 'month', 'day', 'hour', 'minute', 'second') as $max_granularity) {
|
||||
// Skip invalid combinations.
|
||||
if (in_array($max_granularity, array('year', 'month', 'day')) && $tz_handling != 'none') {
|
||||
@ -182,17 +192,32 @@ class DateTimezoneTestCase extends DateFieldBasic {
|
||||
case 'hour':
|
||||
$edit[$field_name . '[und][0][value][date]'] = '10/07/2010 - 10';
|
||||
$edit[$field_name . '[und][0][value2][date]'] = '10/07/2010 - 11';
|
||||
$should_be = 'Thu, 10/07/2010 - 10 to Thu, 10/07/2010 - 11';
|
||||
if ($tz_handling == 'utc') {
|
||||
$should_be = 'Thu, 10/07/2010 - 21 to Thu, 10/07/2010 - 22';
|
||||
}
|
||||
else {
|
||||
$should_be = 'Thu, 10/07/2010 - 10 to Thu, 10/07/2010 - 11';
|
||||
}
|
||||
break;
|
||||
case 'minute':
|
||||
$edit[$field_name . '[und][0][value][date]'] = '10/07/2010 - 10:30';
|
||||
$edit[$field_name . '[und][0][value2][date]'] = '10/07/2010 - 11:30';
|
||||
$should_be = 'Thu, 10/07/2010 - 10:30 to 11:30';
|
||||
if ($tz_handling == 'utc') {
|
||||
$should_be = 'Thu, 10/07/2010 - 21:30 to 22:30';
|
||||
}
|
||||
else {
|
||||
$should_be = 'Thu, 10/07/2010 - 10:30 to 11:30';
|
||||
}
|
||||
break;
|
||||
case 'second':
|
||||
$edit[$field_name . '[und][0][value][date]'] = '10/07/2010 - 10:30:30';
|
||||
$edit[$field_name . '[und][0][value2][date]'] = '10/07/2010 - 11:30:30';
|
||||
$should_be = 'Thu, 10/07/2010 - 10:30:30 to 11:30:30';
|
||||
if ($tz_handling == 'utc') {
|
||||
$should_be = 'Thu, 10/07/2010 - 21:30:30 to 22:30:30';
|
||||
}
|
||||
else {
|
||||
$should_be = 'Thu, 10/07/2010 - 10:30:30 to 11:30:30';
|
||||
}
|
||||
break;
|
||||
}
|
||||
$this->drupalPost('node/add/story', $edit, t('Save'));
|
||||
|
@ -88,4 +88,4 @@ Known Issue http://drupal.org/node/207859
|
||||
secure pages doesn't know about. When trying to make non-secure ajax calls
|
||||
from a secure page, the browser denies the call.
|
||||
Solution:
|
||||
The solution is to simply add panels/* to your Secure Pages configuration.
|
||||
The solution is to simply add panels/* to your Secure Pages configuration.
|
||||
|
@ -1,3 +1,3 @@
|
||||
Welcome to Panels 3
|
||||
|
||||
Documentation is available at https://www.drupal.org/node/496278
|
||||
Documentation is available at https://www.drupal.org/node/496278
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
.dashboard-entry .dashboard-link {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
div.panel-pane div.admin-links {
|
||||
font-size: xx-small;
|
||||
margin-right: 1em;
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
.layout-link {
|
||||
float: left;
|
||||
padding: 1em;
|
||||
@ -141,12 +140,12 @@ table .argument-operation input {
|
||||
}
|
||||
|
||||
tr.changed td {
|
||||
background-color: #FFFFDD !important;
|
||||
background-color: #ffffdd !important;
|
||||
}
|
||||
|
||||
tr.changed td span.star {
|
||||
font-weight: bold;
|
||||
color: #E09010;
|
||||
color: #e09010;
|
||||
}
|
||||
|
||||
td select {
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#panels-dnd-main {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
@ -42,7 +41,7 @@ div.panels-set-title-hide .panels-set-title {
|
||||
}
|
||||
|
||||
/* Add Icon */
|
||||
#panels-dnd-main div.panel-region .pane-add-link {
|
||||
#panels-dnd-main div.panel-region .pane-add-link {
|
||||
}
|
||||
#panels-dnd-main div.panel-region .pane-add-link img {
|
||||
display: none;
|
||||
@ -127,24 +126,24 @@ div.panels-set-title-hide .panel-pane-is-title {
|
||||
}
|
||||
|
||||
.panel-portlet .changed div.grab-title {
|
||||
background-color: #FFFFDD !important;
|
||||
border-bottom: 1px solid #3D9CD7 !important;
|
||||
background-color: #ffffdd !important;
|
||||
border-bottom: 1px solid #3d9cd7 !important;
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
.panel-portlet .changed.hidden-pane div.grab-title {
|
||||
background-color: #B4B488 !important;
|
||||
border-bottom: 1px solid #3D9CD7 !important;
|
||||
background-color: #b4b488 !important;
|
||||
border-bottom: 1px solid #3d9cd7 !important;
|
||||
}
|
||||
|
||||
.panel-portlet .changed div.grab-title span.star {
|
||||
font-weight: bold;
|
||||
color: #E09010;
|
||||
color: #e09010;
|
||||
}
|
||||
|
||||
.panel-portlet .grabber:hover {
|
||||
color: #fff;
|
||||
background-color: #2F78A5;
|
||||
background-color: #2f78a5;
|
||||
}
|
||||
|
||||
.panel-portlet.hidden-pane .grab-title:hover {
|
||||
@ -175,7 +174,8 @@ div.panels-set-title-hide .panel-pane-is-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.panel-portlet .buttons input, .panel-portlet .buttons button {
|
||||
.panel-portlet .buttons input,
|
||||
.panel-portlet .buttons button {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: inline;
|
||||
@ -186,7 +186,7 @@ div.panels-set-title-hide .panel-pane-is-title {
|
||||
}
|
||||
|
||||
.panel-portlet .pane-title {
|
||||
font-size:110%;
|
||||
font-size: 110%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@ -315,7 +315,7 @@ a.close img {
|
||||
padding-left: 1em;
|
||||
padding-bottom: 1em;
|
||||
margin-bottom: 1em;
|
||||
background-color: #EEEEEE;
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.panels-section-columns {
|
||||
@ -354,7 +354,7 @@ a.close img {
|
||||
|
||||
.panels-section-column-categories .inside {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.panels-section-column-categories .content-type-button {
|
||||
padding-left: 10px;
|
||||
@ -431,7 +431,7 @@ a.close img {
|
||||
float: none;
|
||||
}
|
||||
|
||||
.panels-modal-content .modal-form .no-float label {
|
||||
.panels-modal-content .modal-form .no-float label {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@ -502,7 +502,6 @@ html.js div.panels-display-links div.ctools-dropdown-container ul li a {
|
||||
/* @group CTools Dropdown */
|
||||
#panels-dnd-main .ctools-dropdown a.ctools-dropdown-text-link,
|
||||
html.js div.panels-display-links a.ctools-dropdown-text-link {
|
||||
|
||||
background: url('../images/arrow-down-light.png') 0 3px no-repeat!important;
|
||||
padding-left: 12px;
|
||||
}
|
||||
@ -522,7 +521,6 @@ html.js div.panels-display-links div.ctools-dropdown-container {
|
||||
|
||||
html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li,
|
||||
html.js div.panels-display-links div.ctools-dropdown-container ul li {
|
||||
|
||||
text-decoration: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
@ -565,7 +563,7 @@ html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li
|
||||
html.js div.panels-display-links div.ctools-dropdown-container ul li .panels-sub-menu ul li a,
|
||||
html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li .panels-sub-menu span.panels-text,
|
||||
html.js div.panels-display-links div.ctools-dropdown-container ul li .panels-sub-menu span.panels-text {
|
||||
width:auto;
|
||||
width: auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
@ -682,4 +680,3 @@ div.ctools-modal-content {
|
||||
top: -2em;
|
||||
margin-bottom: -2em;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
div.panels-page-type-container {
|
||||
clear: left;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Internationalization (i18n) hooks
|
||||
* Internationalization (i18n) hooks.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -7,9 +7,9 @@ dependencies[] = i18n_translation
|
||||
package = Multilingual - Internationalization
|
||||
core = 7.x
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-10-16
|
||||
version = "7.x-3.8"
|
||||
; Information added by Drupal.org packaging script on 2017-02-06
|
||||
version = "7.x-3.9"
|
||||
core = "7.x"
|
||||
project = "panels"
|
||||
datestamp = "1476582295"
|
||||
datestamp = "1486394388"
|
||||
|
||||
|
@ -206,6 +206,7 @@ function i18n_panels_panels_delete_display($did) {
|
||||
*
|
||||
* This function must not rely on the passed $renderer parameter. The parameter
|
||||
* could be empty because this function is reused in i18n_ctools_render_alter().
|
||||
*
|
||||
* @todo Check if a drupal_alter() in panels_display::get_title() is applicable.
|
||||
*
|
||||
* @see i18n_ctools_render_alter()
|
||||
@ -234,6 +235,7 @@ function i18n_panels_panels_pre_render(&$display, $renderer) {
|
||||
*
|
||||
* Under some circumstances the title of the panel page is set before
|
||||
* hook_panels_pre_render() is fired. Such cases can be handled with this hook.
|
||||
*
|
||||
* @todo Check if a drupal_alter() in panels_display::get_title() is applicable.
|
||||
*/
|
||||
function i18n_ctools_render_alter(&$info, $page, $context) {
|
||||
@ -250,7 +252,6 @@ function i18n_ctools_render_alter(&$info, $page, $context) {
|
||||
* Implements hook_ctools_plugin_post_alter().
|
||||
*
|
||||
* Register some translatable configuration settings for plugins.
|
||||
*
|
||||
*/
|
||||
function i18n_panels_ctools_plugin_post_alter(&$plugin, $plugin_type_info) {
|
||||
if ($plugin_type_info['type'] == 'content_types') {
|
||||
@ -322,7 +323,7 @@ function i18n_panels_i18n_string_list($group) {
|
||||
if (empty($pane->uuid)) {
|
||||
// Fetch exported uuid and validate it.
|
||||
$uuid = str_replace('new-', '', $pane->pid);
|
||||
if (!panels_uuid_is_valid($uuid)) {
|
||||
if (!ctools_uuid_is_valid($uuid)) {
|
||||
drupal_set_message(t('The pane %pane has no uuid, please resave or re-export it.', array('%pane' => $pane->pid)), 'warning');
|
||||
continue;
|
||||
}
|
||||
@ -366,7 +367,7 @@ function _18n_panels_is_exported_panels_display($display) {
|
||||
*
|
||||
* @todo I bet there are better ways to solve this mess.
|
||||
*
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* Reset the static cache.
|
||||
*
|
||||
* @return array
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user