The Input formats - filter patch has landed. I still need to make update instructions for modules and update the hook docs.

Here's an overview of the changes:
1) Multiple Input formats: they are complete filter configurations (what filters to use, in what order and with which settings). Input formats are admin-definable, and usage of them is role-dependant. For example, you can set it up so that regular users can only use limited HTML, while admins can free HTML without any tag limitations.
The input format can be chosen per content item (nodes, comments, blocks, ...) when you add/edit them. If only a single format is available, there is no choice, and nothing changes with before.

The default install (and the upgrade) contains a basic set of formats which should satisfy the average user's needs.

2) Filters have toggles
Because now you might want to enable a filter only on some input formats, an explicit toggle is provided by the filter system. Modules do not need to worry about it and filters that still have their own on/off switch should get rid of it.

3) Multiple filters per module
This was necessary to accomodate the next change, and it's also a logical extension of the filter system.

4) Embedded PHP is now a filter
Thanks to the multiple input formats, I was able to move the 'embedded PHP' feature from block.module, page.module and book.module into a simple filter which executes PHP code. This filter is part of filter.module, and by default there is an input format 'PHP', restricted to the administrator only, which contains this filter.
This change means that block.module now passes custom block contents through the filter system.
As well as from reducing code duplication and avoiding two type selectors for page/book nodes, you can now combine PHP code with other filters.

5) User-supplied PHP code now requires <?php ?> tags.
This is required for teasers to work with PHP code. Because PHP evaluation is now just another step in the filter process, we can't do this. Also, because teasers are generated before filtering, this would result in errors when the teaser generation would cut off a piece of PHP code.

Also, regular PHP syntax explicitly includes the <?php ?> tags for PHP files, so it makes sense to use the same convention for embedded PHP in Drupal.

6) Filter caching was added.
Benchmarking shows that even for a simple setup (basic html filtering + legacy URL rewriting), filtercache can offer speedups. Unlike the old filtercache, this uses the normal cache table.

7) Filtertips were moved from help into a hook_filter_tips(). This was required to accomodate the fact that there are multiple filters per module, and that filter settings are format dependant. Shoehorning filter tips into _help was ugly and silly. The display of the filter tips is done through the input format selector, so filter_tips_short() no longer exists.

8) A more intelligent linebreak convertor was added, which doesn't stop working if you use block-level tags and which adds <p> tags.
4.5.x
Steven Wittens 2004-08-10 18:34:29 +00:00
parent 09fc61c065
commit 660f99287d
32 changed files with 1925 additions and 572 deletions

View File

@ -135,7 +135,6 @@ CREATE TABLE book (
nid int(10) unsigned NOT NULL default '0',
parent int(10) NOT NULL default '0',
weight tinyint(3) NOT NULL default '0',
format tinyint(2) default '0',
log longtext,
PRIMARY KEY (nid),
KEY parent (parent)
@ -150,7 +149,7 @@ CREATE TABLE boxes (
title varchar(64) NOT NULL default '',
body longtext,
info varchar(128) NOT NULL default '',
type tinyint(2) NOT NULL default '0',
format int(4) NOT NULL default '0',
PRIMARY KEY (bid),
UNIQUE KEY title (title),
UNIQUE KEY info (info)
@ -184,6 +183,7 @@ CREATE TABLE comments (
timestamp int(11) NOT NULL default '0',
score mediumint(9) NOT NULL default '0',
status tinyint(3) unsigned NOT NULL default '0',
format int(4) NOT NULL default '0',
thread varchar(255) NOT NULL,
users longtext,
name varchar(60) default NULL,
@ -207,14 +207,28 @@ CREATE TABLE directory (
PRIMARY KEY (link)
) TYPE=MyISAM;
--
-- Table structure for table 'filter_formats'
--
CREATE TABLE filter_formats (
format int(4) NOT NULL default '0' auto_increment,
name varchar(255) NOT NULL default '',
roles varchar(255) NOT NULL default '',
cache tinyint(2) NOT NULL default '0',
PRIMARY KEY format (format)
) TYPE=MyISAM;
--
-- Table structure for table 'filters'
--
CREATE TABLE filters (
format int(4) NOT NULL default '0',
module varchar(64) NOT NULL default '',
delta tinyint(2) DEFAULT '0' NOT NULL,
weight tinyint(2) DEFAULT '0' NOT NULL,
KEY module (module)
INDEX (weight)
) TYPE=MyISAM;
--
@ -330,6 +344,7 @@ CREATE TABLE node (
body longtext NOT NULL,
revisions longtext NOT NULL,
sticky int(2) NOT NULL default '0',
format int(4) NOT NULL default '0',
PRIMARY KEY (nid),
KEY node_type (type(4)),
KEY node_title_type (title,type(4)),
@ -362,7 +377,6 @@ CREATE TABLE node_access (
CREATE TABLE page (
nid int(10) unsigned NOT NULL default '0',
link varchar(128) NOT NULL default '',
format tinyint(2) NOT NULL default '0',
description varchar(128) NOT NULL default '',
PRIMARY KEY (nid)
) TYPE=MyISAM;
@ -700,3 +714,12 @@ REPLACE blocks SET module = 'user', delta = '1', status = '1';
INSERT INTO sequences (name, id) VALUES ('menu_mid', 1);
INSERT INTO node_access VALUES (0, 0, 'all', 1, 0, 0);
INSERT INTO filter_formats VALUES (1,'Filtered HTML',',1,2,',1);
INSERT INTO filter_formats VALUES (2,'PHP code','',0);
INSERT INTO filter_formats VALUES (3,'Full HTML','',1);
INSERT INTO filters VALUES (1,'filter',0,0);
INSERT INTO filters VALUES (1,'filter',3,1);
INSERT INTO filters VALUES (2,'filter',1,0);
INSERT INTO filters VALUES (3,'filter',3,0);
INSERT INTO variable (name,value) VALUES ('filter_html_1','i:1;');

View File

@ -694,6 +694,16 @@ INSERT INTO permission VALUES (2,'access comments, access content, post comments
INSERT INTO blocks(module,delta,status) VALUES('user', '0', '1');
INSERT INTO blocks(module,delta,status) VALUES('user', '1', '1');
INSERT INTO filter_formats VALUES (1,'Filtered HTML',',1,2,',1);
INSERT INTO filter_formats VALUES (2,'PHP code','',0);
INSERT INTO filter_formats VALUES (3,'Full HTML','',1));
INSERT INTO filters VALUES (1,'filter',0,0);
INSERT INTO filters VALUES (1,'filter',3,1);
INSERT INTO filters VALUES (2,'filter',1,0);
INSERT INTO filters VALUES (3,'filter',3,0);
INSERT INTO variable (name,value) VALUES ('filter_html_1','i:1;');
---
--- Functions
---

View File

@ -69,7 +69,8 @@ $sql_updates = array(
"2004-07-30" => "update_95",
"2004-08-04" => "update_96",
"2004-08-06" => "update_97",
"2004-08-07" => "update_98"
"2004-08-07" => "update_98",
"2004-08-09" => "update_99"
);
function update_32() {
@ -1308,6 +1309,159 @@ function update_98() {
return array();
}
function update_99() {
// Filter patch - Multiple input formats
$ret = array();
/*
** Load the list of PHP book and page nodes.
*/
$php_nodes = array();
$res = db_query("SELECT nid FROM {book} WHERE format = 1");
while ($book = db_fetch_object($res)) {
$php_nodes[] = $book->nid;
}
$res = db_query("SELECT nid FROM {page} WHERE format = 1");
while ($page = db_fetch_object($res)) {
$php_nodes[] = $page->nid;
}
/*
** Apply database changes
*/
if ($GLOBALS['db_type'] == 'mysql') {
// Filters table
$ret[] = update_sql("ALTER TABLE {filters} ADD format int(4) NOT NULL default '0'");
$ret[] = update_sql("ALTER TABLE {filters} ADD delta tinyint(2) NOT NULL default '0'");
// Filter_formats table
$ret[] = update_sql("CREATE TABLE {filter_formats} (
format int(4) NOT NULL auto_increment,
name varchar(255) NOT NULL default '',
roles varchar(255) NOT NULL default '',
cache tinyint(2) NOT NULL default '1',
PRIMARY KEY (format)
)");
// Store formats in nodes, comments and boxes
$ret[] = update_sql("ALTER TABLE {boxes} CHANGE type format int(4) NOT NULL default '0'");
$ret[] = update_sql("ALTER TABLE {comments} ADD format int(4) NOT NULL default '0'");
$ret[] = update_sql("ALTER TABLE {node} ADD format int(4) NOT NULL default '0'");
// Get rid of the old book/page type info
$ret[] = update_sql("ALTER TABLE {book} DROP format");
$ret[] = update_sql("ALTER TABLE {page} DROP format");
}
else if ($GLOBALS['db_type'] == 'pgsql') {
// TODO: add pgsql equivalent. Whoever does this should pay attention that
// the keys/indices for the 'filters' table are correct. There was some
// inconsistency between the MySQL and PGSQL version before.
}
// Initialize all nodes and comments to the legacy format (see below)
$ret[] = update_sql("UPDATE {node} SET format = 1");
$ret[] = update_sql("UPDATE {comments} SET format = 1");
// Set format to PHP for the old PHP book/page nodes.
if (count($php_nodes)) {
$ret[] = update_sql("UPDATE {node} SET format = 2 WHERE nid IN (". implode(',', $php_nodes) .")");
}
// Boxes now use the filtering system as well.
// Type 0 (HTML) maps to Format 3 (Full HTML).
// Type 1 (PHP) maps to Format 2 (PHP).
$ret[] = update_sql("UPDATE {boxes} SET format = 3 - format");
/*
** Update PHP content to use <?php ?> tags.
*/
if ($GLOBALS['db_type'] == 'mysql') {
$ret[] = update_sql("UPDATE {node} SET teaser = CONCAT('<?php ', teaser) WHERE format = 2");
$ret[] = update_sql("UPDATE {node} SET body = CONCAT('<?php ', body) WHERE format = 2");
$ret[] = update_sql("UPDATE {boxes} SET body = CONCAT('<?php ', body) WHERE format = 2");
}
else if ($GLOBALS['db_type'] == 'pgsql') {
// TODO: someone needs to verify if this works.
$ret[] = update_sql("UPDATE {node} SET teaser = '<?php ' || teaser WHERE format = 2");
$ret[] = update_sql("UPDATE {node} SET body = '<?php ' || body WHERE format = 2");
$ret[] = update_sql("UPDATE {boxes} SET body = '<?php ' || body WHERE format = 2");
}
/*
** We now set up some input formats. One of these is a 'legacy' format which
** tries to preserve as much settings as possible from before the patch.
** The other two are 'PHP code' and 'Full HTML'.
*/
// We pick an appropriate name for the legacy format.
$old_html_filter = variable_get('filter_html', 0);
if ($old_html_filter == FILTER_HTML_ESCAPE) {
$default = 'Plain text';
}
else {
$default = 'Filtered HTML';
}
// Make sure the legacy format is accessible to all roles
$all_roles = array_keys(user_roles());
$ret[] = update_sql("INSERT INTO {filter_formats} VALUES (1,'$default',',". implode(',', $all_roles) .",',1)");
// Determine which roles have the old 'create php content' permission.
$res = db_query("SELECT rid FROM {permission} WHERE perm LIKE '%create php content%'");
$php_roles = array();
while ($role = db_fetch_object($res)) {
$php_roles[] = $role->rid;
}
$ret[] = update_sql("INSERT INTO {filter_formats} VALUES (2,'PHP code','". implode(',', $php_roles) .",',0)");
// This is a 'Full HTML' format which allows all HTML without restrictions.
$ret[] = update_sql("INSERT INTO {filter_formats} VALUES (3,'Full HTML','',1)");
// Set the default format to the legacy format
variable_set('filter_default_format', 1);
// Put the old filters into the legacy format
$ret[] = update_sql("UPDATE {filters} SET format = 1");
// Add filter.module's standard filters (these used to be hardcoded).
if (!variable_get('rewrite_old_urls', 0)) {
$ret[] = update_sql("DELETE FROM {filters} WHERE module = 'filter'");
}
else {
$ret[] = update_sql("UPDATE {filters} SET delta = 2 WHERE module ='filter'");
}
if ($old_html_filter != 0) {
$ret[] = update_sql("INSERT INTO {filters} (format, module, delta, weight) VALUES (1,'filter',0,0)"); // HTML tag/style filter
}
$ret[] = update_sql("INSERT INTO {filters} (format, module, delta, weight) VALUES (1,'filter',3,1)"); // Linebreak filter
$ret[] = update_sql("INSERT INTO {filters} (format, module, delta, weight) VALUES (2,'filter',1,0)"); // PHP evaluator
$ret[] = update_sql("INSERT INTO {filters} (format, module, delta, weight) VALUES (3,'filter',3,0)"); // Linebreak filter
// Migrate the settings for all core/contrib filtering modules into the legacy
// format.
$migrate = array('filter_html', // filter.module
'allowed_html',
'filter_style',
'anyfilter_regexps', // anyfilter.module
'htmlcorrector_smartclose', // htmlcorrector.module
'htmlcorrector_xhtmlify',
'htmlcorrector_valueentities',
'project_filter', // project.module
'latex_filter_link' // latex.module
);
foreach ($migrate as $variable) {
$value = variable_get($variable, NULL);
if ($value != NULL) {
variable_set($variable .'_1', $value);
variable_del($variable);
}
}
return $ret;
}
function update_sql($sql) {
$edit = $_POST["edit"];
$result = db_query($sql);

View File

@ -133,13 +133,22 @@ function cache_set($cid, $data, $expire = 0, $headers = NULL) {
* @param $cid
* If set, the cache ID to delete. Otherwise, all cache entries that can expire
* are deleted.
*
* @param $wildcard
* If set to true, the $cid is treated as a substring to match rather than a
* complete ID.
*/
function cache_clear_all($cid = NULL) {
function cache_clear_all($cid = NULL, $wildcard = false) {
if (empty($cid)) {
db_query("DELETE FROM {cache} WHERE expire <> 0");
}
else {
db_query("DELETE FROM {cache} WHERE cid = '%s'", $cid);
if ($wildcard) {
db_query("DELETE FROM {cache} WHERE cid LIKE '%%%s%%'", $cid);
}
else {
db_query("DELETE FROM {cache} WHERE cid = '%s'", $cid);
}
}
}

View File

@ -813,7 +813,7 @@ function format_rss_item($title, $link, $description, $args = array()) {
$output = "<item>\n";
$output .= ' <title>'. drupal_specialchars(strip_tags($title)) ."</title>\n";
$output .= ' <link>'. drupal_specialchars(strip_tags($link)) ."</link>\n";
$output .= ' <description>'. drupal_specialchars(check_output($description)) ."</description>\n";
$output .= ' <description>'. drupal_specialchars($description) ."</description>\n";
foreach ($args as $key => $value) {
$output .= ' <'. $key .'>'. drupal_specialchars(strip_tags($value)) ."</$key>\n";
}
@ -1770,6 +1770,20 @@ function truncate_utf8($string, $len) {
return substr($string, 0, $len);
}
/**
* Wrapper around PHP's eval(). Uses output buffering to capture both returned
* and printed text. Unlike eval(), we require code to be surrounded by <?php ?>
* tags (in other words, we evaluate the code as if it were a stand-alone PHP
* file).
*
* @param $code The code to evaluate
*/
function drupal_eval($code) {
ob_start();
print eval('?>'. $code);
return ob_get_clean();
}
include_once 'includes/theme.inc';
include_once 'includes/pager.inc';
include_once 'includes/menu.inc';

View File

@ -319,6 +319,13 @@ tr.light .form-item, tr.dark .form-item {
margin: 0;
font-size: 0.8em;
}
.tips {
margin-top: 0px;
margin-bottom: 0px;
padding-top: 0px;
padding-bottom: 0px;
font-size: 0.9em;
}
#forum .description {
font-size: 0.9em;
margin: 0.5em;

View File

@ -470,7 +470,12 @@ function aggregator_parse_feed(&$data, $feed) {
// Prepare the item:
foreach ($item as $key => $value) {
$item[$key] = filter_default(strtr(trim($value), $tt));
// TODO: Make handling of aggregated HTML more flexible/configurable.
$value = strtr(trim($value), $tt);
$value = strip_tags($value, '<a> <b> <br> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>');
$value = preg_replace('/\Wstyle\s*=[^>]+?>/i', '>', $value);
$value = preg_replace('/\Won[a-z]+\s*=[^>]+?>/i', '>', $value);
$item[$key] = $value;
}
/*

View File

@ -470,7 +470,12 @@ function aggregator_parse_feed(&$data, $feed) {
// Prepare the item:
foreach ($item as $key => $value) {
$item[$key] = filter_default(strtr(trim($value), $tt));
// TODO: Make handling of aggregated HTML more flexible/configurable.
$value = strtr(trim($value), $tt);
$value = strip_tags($value, '<a> <b> <br> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>');
$value = preg_replace('/\Wstyle\s*=[^>]+?>/i', '>', $value);
$value = preg_replace('/\Won[a-z]+\s*=[^>]+?>/i', '>', $value);
$item[$key] = $value;
}
/*

View File

@ -8,7 +8,7 @@ function block_help($section) {
switch ($section) {
case 'admin/help#block':
return t("
<p>Blocks are the boxes visible in the sidebar(s) of your web site. These are usually generated automatically by modules (e.g. recent forum topics), but you can also create your own blocks using either static HTML or dynamic PHP content.</p>
<p>Blocks are the boxes visible in the sidebar(s) of your web site. These are usually generated automatically by modules (e.g. recent forum topics), but you can also create your own blocks.</p>
<p>The sidebar each block appears in depends on both which theme you're using (some are left-only, some right, some both), and on the settings in block management.</p><p>Whether a block is visible in the first place depends on four things:</p><ul><li>It must have its \"enabled\" box checked in block management.</li><li>If it has its \"custom\" box checked in block management, the user must have chosen to display it in their user preferences.</li><li>If the \"path\" field in block management is set, the visitor must be on a page that matches the path specification (more on this later).</li><li>If the block has its throttle box checked, the user will only see the block if the site throttle level is low.</li></ul>
<p>The block management screen also lets you specify the vertical sort-order of the blocks within a sidebar. You do this by assigning a <strong>weight</strong> to each block. Lighter blocks (smaller weight) \"float up\" towards the top of the sidebar. Heavier ones \"sink down\" towards the bottom of it.</p>
<p>The path setting lets you define the pages on which a specific block is visible. If you leave the path blank it will appear on all pages. The path uses a regular expression syntax so remember to escape special characters! The path expression is matched against the relative URL of a Drupal page, e.g. <code>book</code>, <code>node/12</code>, <code>admin</code>.</p>
@ -16,26 +16,7 @@ function block_help($section) {
<p>However, for basic tasks it is sufficient to look at the following examples:</p>
<p>If the block should only show up on blog pages, use &lt;^blog&gt;. To display on all node views use &lt;^node&gt;. The angular brackets are used as delimiters of the regular expression. To show up on either forum or book pages use &lt;^(forum|book)&gt;. The round brackets form a group of expressions, divided by the | character. It matches if any of the expressions in it match. A more complicated example is &lt;^node/add/(story|blog|image)&gt;. Blocks which have their paths set to this expression will show up on story, block, or image composition pages. If you want to show a block an all pages, but not the search page, use &lt;^(?!search)&gt;.</p>
<h3>Administrator Defined Blocks</h3>
<p>An administrator defined block contains HTML, text or PHP content supplied by you (as opposed to being generated automatically by a module). Each admin-defined block consists of a title, a description, and a body containing text, HTML, or PHP code which can be as long as you wish. The Drupal engine will 'render' the content of the block.</p>
<h4>PHP in admin-defined blocks</h4>
<p>If you know how to script in PHP, Drupal gives you the power to embed any script you like inside a block. It will be executed when the page is viewed and dynamically embedded into the page. This gives you amazing flexibility and power, but of course with that comes danger and insecurity if you don't write good code. If you are not familiar with PHP, SQL or with the site engine, avoid experimenting with PHP blocks because you can corrupt your database or render your site insecure or even unusable! If you don't plan to do fancy stuff with your blocks then you're probably better off with straight HTML.</p>
<p>Remember that the code within each PHP block must be valid PHP code - including things like correctly terminating statements with a semicolon so that the parser won't die. It is highly recommended that you develop your blocks separately using a simple test script on top of a test database before migrating to your production environment.</p>
<p>Notes:</p><ul><li>You can use global variables, such as configuration parameters, within the scope of a PHP box but remember that variables which have been given values in a PHP box will retain these values in the engine or module afterwards.</li><li>register_globals is now set to <strong>off</strong> by default. If you need form information you need to get it from the \"superglobals\" \$_POST, \$_GET, etc.</li><li>You should use the <code>return</code> statement to return the actual content for your block.</li></ul>
<p>A basic example:</p>
<blockquote><p>You want to have a box with the title \"Welcome\" that you use to greet your visitors. The content for this box could be created by going:</p>
<pre>
return t(\"Welcome visitor, ... welcome message goes here ...\");
</pre>
<p>If we are however dealing with a registered user, we can customize the message by using:</p>
<pre>
if (\$user->uid) {
return t(\"Welcome \$user->name, ... welcome message goes here ...\");
}
else {
return t(\"Welcome visitor, ... welcome message goes here ...\");
}
</pre></blockquote>
<p>For more in-depth examples, we recommend that you check the existing boxes and use them as a starting point.</p>", array('%pcre' => 'http://php.net/pcre/'));
<p>An administrator defined block contains content supplied by you (as opposed to being generated automatically by a module). Each admin-defined block consists of a title, a description, and a body which can be as long as you wish. The Drupal engine will 'render' the content of the block.</p>", array('%pcre' => 'http://php.net/pcre/'));
case 'admin/modules#description':
return t('Controls the boxes that are displayed around the main content.');
case 'admin/block':
@ -101,7 +82,7 @@ function block_block($op = 'list', $delta = 0) {
else {
$block = db_fetch_object(db_query('SELECT * FROM {boxes} WHERE bid = %d', $delta));
$data['subject'] = $block->title;
$data['content'] = ($block->type == 1) ? eval($block->body) : $block->body;
$data['content'] = check_output($block->body, $block->format);
return $data;
}
}
@ -179,11 +160,20 @@ function block_admin_display() {
$blocks = _block_rehash();
// Fetch input formats used by admin-defined boxes.
$formats = array();
$result = db_query('SELECT bid, format FROM {boxes}');
while ($box = db_fetch_object($result)) {
$formats[$box->bid] = $box->format;
}
$header = array(t('block'), t('enabled'), t('custom'), t('throttle'), t('weight'), t('region'), t('path'), array('data' => t('operations'), 'colspan' => 2));
foreach ($blocks as $block) {
if ($block['module'] == 'block') {
$edit = l(t('edit'), 'admin/block/edit/'. $block['delta']);
if (filter_access($formats[$block['delta']])) {
$edit = l(t('edit'), 'admin/block/edit/'. $block['delta']);
}
$delete = l(t('delete'), 'admin/block/delete/'. $block['delta']);
}
else {
@ -232,14 +222,10 @@ function block_box_edit($bid = 0) {
}
function block_box_form($edit = array()) {
$type = array(0 => 'HTML', 1 => 'PHP');
$group = form_textfield(t('Block title'), 'title', $edit['title'], 50, 64, t('The title of the block as shown to the user.'));
$group .= filter_form('format', $edit['format']);
$group .= form_textarea(t('Block body'), 'body', $edit['body'], 70, 10, t('The content of the block as shown to the user.'));
$group .= form_textfield(t('Block description'), 'info', $edit['info'], 50, 64, t('A brief description of your block. Used on the <a href="%overview">block overview page</a>.', array('%overview' => url('admin/block'))));
if (user_access('create php content')) {
$group .= form_radios(t('Block type'), 'type', $edit['type'], $type, t("If you would like to use PHP code inside your block, set the above option to 'PHP' instead of 'HTML'."));
}
if ($edit['bid']) {
$group .= form_hidden('bid', $edit['bid']);
@ -252,16 +238,16 @@ function block_box_form($edit = array()) {
}
function block_box_save($edit) {
if (!user_access('create php content')) {
$edit['type'] = 0;
if (!filter_access($edit['format'])) {
$edit['format'] = FILTER_FORMAT_DEFAULT;
}
if ($edit['bid']) {
db_query("UPDATE {boxes} SET title = '%s', body = '%s', info = '%s', type = %d WHERE bid = %d", $edit['title'], $edit['body'], $edit['info'], $edit['type'], $edit['bid']);
db_query("UPDATE {boxes} SET title = '%s', body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['title'], $edit['body'], $edit['info'], $edit['format'], $edit['bid']);
return t('the block has been updated.');
}
else {
db_query("INSERT INTO {boxes} (title, body, info, type) VALUES ('%s', '%s', '%s', %d)", $edit['title'], $edit['body'], $edit['info'], $edit['type']);
db_query("INSERT INTO {boxes} (title, body, info, format) VALUES ('%s', '%s', '%s', %d)", $edit['title'], $edit['body'], $edit['info'], $edit['format']);
return t('the new block has been added.');
}
}

View File

@ -8,7 +8,7 @@ function block_help($section) {
switch ($section) {
case 'admin/help#block':
return t("
<p>Blocks are the boxes visible in the sidebar(s) of your web site. These are usually generated automatically by modules (e.g. recent forum topics), but you can also create your own blocks using either static HTML or dynamic PHP content.</p>
<p>Blocks are the boxes visible in the sidebar(s) of your web site. These are usually generated automatically by modules (e.g. recent forum topics), but you can also create your own blocks.</p>
<p>The sidebar each block appears in depends on both which theme you're using (some are left-only, some right, some both), and on the settings in block management.</p><p>Whether a block is visible in the first place depends on four things:</p><ul><li>It must have its \"enabled\" box checked in block management.</li><li>If it has its \"custom\" box checked in block management, the user must have chosen to display it in their user preferences.</li><li>If the \"path\" field in block management is set, the visitor must be on a page that matches the path specification (more on this later).</li><li>If the block has its throttle box checked, the user will only see the block if the site throttle level is low.</li></ul>
<p>The block management screen also lets you specify the vertical sort-order of the blocks within a sidebar. You do this by assigning a <strong>weight</strong> to each block. Lighter blocks (smaller weight) \"float up\" towards the top of the sidebar. Heavier ones \"sink down\" towards the bottom of it.</p>
<p>The path setting lets you define the pages on which a specific block is visible. If you leave the path blank it will appear on all pages. The path uses a regular expression syntax so remember to escape special characters! The path expression is matched against the relative URL of a Drupal page, e.g. <code>book</code>, <code>node/12</code>, <code>admin</code>.</p>
@ -16,26 +16,7 @@ function block_help($section) {
<p>However, for basic tasks it is sufficient to look at the following examples:</p>
<p>If the block should only show up on blog pages, use &lt;^blog&gt;. To display on all node views use &lt;^node&gt;. The angular brackets are used as delimiters of the regular expression. To show up on either forum or book pages use &lt;^(forum|book)&gt;. The round brackets form a group of expressions, divided by the | character. It matches if any of the expressions in it match. A more complicated example is &lt;^node/add/(story|blog|image)&gt;. Blocks which have their paths set to this expression will show up on story, block, or image composition pages. If you want to show a block an all pages, but not the search page, use &lt;^(?!search)&gt;.</p>
<h3>Administrator Defined Blocks</h3>
<p>An administrator defined block contains HTML, text or PHP content supplied by you (as opposed to being generated automatically by a module). Each admin-defined block consists of a title, a description, and a body containing text, HTML, or PHP code which can be as long as you wish. The Drupal engine will 'render' the content of the block.</p>
<h4>PHP in admin-defined blocks</h4>
<p>If you know how to script in PHP, Drupal gives you the power to embed any script you like inside a block. It will be executed when the page is viewed and dynamically embedded into the page. This gives you amazing flexibility and power, but of course with that comes danger and insecurity if you don't write good code. If you are not familiar with PHP, SQL or with the site engine, avoid experimenting with PHP blocks because you can corrupt your database or render your site insecure or even unusable! If you don't plan to do fancy stuff with your blocks then you're probably better off with straight HTML.</p>
<p>Remember that the code within each PHP block must be valid PHP code - including things like correctly terminating statements with a semicolon so that the parser won't die. It is highly recommended that you develop your blocks separately using a simple test script on top of a test database before migrating to your production environment.</p>
<p>Notes:</p><ul><li>You can use global variables, such as configuration parameters, within the scope of a PHP box but remember that variables which have been given values in a PHP box will retain these values in the engine or module afterwards.</li><li>register_globals is now set to <strong>off</strong> by default. If you need form information you need to get it from the \"superglobals\" \$_POST, \$_GET, etc.</li><li>You should use the <code>return</code> statement to return the actual content for your block.</li></ul>
<p>A basic example:</p>
<blockquote><p>You want to have a box with the title \"Welcome\" that you use to greet your visitors. The content for this box could be created by going:</p>
<pre>
return t(\"Welcome visitor, ... welcome message goes here ...\");
</pre>
<p>If we are however dealing with a registered user, we can customize the message by using:</p>
<pre>
if (\$user->uid) {
return t(\"Welcome \$user->name, ... welcome message goes here ...\");
}
else {
return t(\"Welcome visitor, ... welcome message goes here ...\");
}
</pre></blockquote>
<p>For more in-depth examples, we recommend that you check the existing boxes and use them as a starting point.</p>", array('%pcre' => 'http://php.net/pcre/'));
<p>An administrator defined block contains content supplied by you (as opposed to being generated automatically by a module). Each admin-defined block consists of a title, a description, and a body which can be as long as you wish. The Drupal engine will 'render' the content of the block.</p>", array('%pcre' => 'http://php.net/pcre/'));
case 'admin/modules#description':
return t('Controls the boxes that are displayed around the main content.');
case 'admin/block':
@ -101,7 +82,7 @@ function block_block($op = 'list', $delta = 0) {
else {
$block = db_fetch_object(db_query('SELECT * FROM {boxes} WHERE bid = %d', $delta));
$data['subject'] = $block->title;
$data['content'] = ($block->type == 1) ? eval($block->body) : $block->body;
$data['content'] = check_output($block->body, $block->format);
return $data;
}
}
@ -179,11 +160,20 @@ function block_admin_display() {
$blocks = _block_rehash();
// Fetch input formats used by admin-defined boxes.
$formats = array();
$result = db_query('SELECT bid, format FROM {boxes}');
while ($box = db_fetch_object($result)) {
$formats[$box->bid] = $box->format;
}
$header = array(t('block'), t('enabled'), t('custom'), t('throttle'), t('weight'), t('region'), t('path'), array('data' => t('operations'), 'colspan' => 2));
foreach ($blocks as $block) {
if ($block['module'] == 'block') {
$edit = l(t('edit'), 'admin/block/edit/'. $block['delta']);
if (filter_access($formats[$block['delta']])) {
$edit = l(t('edit'), 'admin/block/edit/'. $block['delta']);
}
$delete = l(t('delete'), 'admin/block/delete/'. $block['delta']);
}
else {
@ -232,14 +222,10 @@ function block_box_edit($bid = 0) {
}
function block_box_form($edit = array()) {
$type = array(0 => 'HTML', 1 => 'PHP');
$group = form_textfield(t('Block title'), 'title', $edit['title'], 50, 64, t('The title of the block as shown to the user.'));
$group .= filter_form('format', $edit['format']);
$group .= form_textarea(t('Block body'), 'body', $edit['body'], 70, 10, t('The content of the block as shown to the user.'));
$group .= form_textfield(t('Block description'), 'info', $edit['info'], 50, 64, t('A brief description of your block. Used on the <a href="%overview">block overview page</a>.', array('%overview' => url('admin/block'))));
if (user_access('create php content')) {
$group .= form_radios(t('Block type'), 'type', $edit['type'], $type, t("If you would like to use PHP code inside your block, set the above option to 'PHP' instead of 'HTML'."));
}
if ($edit['bid']) {
$group .= form_hidden('bid', $edit['bid']);
@ -252,16 +238,16 @@ function block_box_form($edit = array()) {
}
function block_box_save($edit) {
if (!user_access('create php content')) {
$edit['type'] = 0;
if (!filter_access($edit['format'])) {
$edit['format'] = FILTER_FORMAT_DEFAULT;
}
if ($edit['bid']) {
db_query("UPDATE {boxes} SET title = '%s', body = '%s', info = '%s', type = %d WHERE bid = %d", $edit['title'], $edit['body'], $edit['info'], $edit['type'], $edit['bid']);
db_query("UPDATE {boxes} SET title = '%s', body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['title'], $edit['body'], $edit['info'], $edit['format'], $edit['bid']);
return t('the block has been updated.');
}
else {
db_query("INSERT INTO {boxes} (title, body, info, type) VALUES ('%s', '%s', '%s', %d)", $edit['title'], $edit['body'], $edit['info'], $edit['type']);
db_query("INSERT INTO {boxes} (title, body, info, format) VALUES ('%s', '%s', '%s', %d)", $edit['title'], $edit['body'], $edit['info'], $edit['format']);
return t('the new block has been added.');
}
}

View File

@ -197,7 +197,7 @@ function blog_form(&$node) {
if ($iid && $item = db_fetch_object(db_query('SELECT i.*, f.title as ftitle, f.link as flink FROM {aggregator_item} i, {aggregator_feed} f WHERE i.iid = %d AND i.fid = f.fid', $iid))) {
$node->title = $item->title;
$node->body = "<a href=\"$item->link\">$item->title</a> - <i>". check_output($item->description) ."</i> [<a href=\"$item->flink\">$item->ftitle</a>]\n";
$node->body = "<a href=\"$item->link\">$item->title</a> - <i>". $item->description ."</i> [<a href=\"$item->flink\">$item->ftitle</a>]\n";
}
}
@ -205,7 +205,7 @@ function blog_form(&$node) {
$output .= implode('', taxonomy_node_form('blog', $node));
}
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 15, filter_tips_short(), NULL, TRUE);
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 15, '', NULL, TRUE);
return $output;
}

View File

@ -197,7 +197,7 @@ function blog_form(&$node) {
if ($iid && $item = db_fetch_object(db_query('SELECT i.*, f.title as ftitle, f.link as flink FROM {aggregator_item} i, {aggregator_feed} f WHERE i.iid = %d AND i.fid = f.fid', $iid))) {
$node->title = $item->title;
$node->body = "<a href=\"$item->link\">$item->title</a> - <i>". check_output($item->description) ."</i> [<a href=\"$item->flink\">$item->ftitle</a>]\n";
$node->body = "<a href=\"$item->link\">$item->title</a> - <i>". $item->description ."</i> [<a href=\"$item->flink\">$item->ftitle</a>]\n";
}
}
@ -205,7 +205,7 @@ function blog_form(&$node) {
$output .= implode('', taxonomy_node_form('blog', $node));
}
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 15, filter_tips_short(), NULL, TRUE);
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 15, '', NULL, TRUE);
return $output;
}

View File

@ -130,6 +130,7 @@ function blogapi_new_post($req_params) {
'promote' => $promote,
'comment' => $comment,
'moderate' => $moderate,
'format' => FILTER_DEFAULT_FORMAT,
'revision' => $revision
));

View File

@ -130,6 +130,7 @@ function blogapi_new_post($req_params) {
'promote' => $promote,
'comment' => $comment,
'moderate' => $moderate,
'format' => FILTER_DEFAULT_FORMAT,
'revision' => $revision
));

View File

@ -39,10 +39,11 @@ function book_access($op, $node) {
// Only registered users can update book pages. Given the nature
// of the book module this is considered to be a good/safe idea.
// One can only update a book page if there are no suggested updates
// of that page waiting for approval, it is not a PHP page, and
// the "create new revision" bit is set. That is, only updates that
// don't overwrite the current or pending information are allowed.
return user_access('maintain books') && !$node->moderate && !$node->format && $node->revision;
// of that page waiting for approval and as long as the "create new
// revision"-bit is set. That is, only updates that don't overwrite
// the current or pending information are allowed.
return user_access('maintain books') && !$node->moderate && $node->revision;
}
}
@ -139,7 +140,7 @@ function book_block($op = 'list', $delta = 0) {
function book_load($node) {
global $user;
$book = db_fetch_object(db_query('SELECT format, parent, weight, log FROM {book} WHERE nid = %d', $node->nid));
$book = db_fetch_object(db_query('SELECT parent, weight, log FROM {book} WHERE nid = %d', $node->nid));
if (arg(1) == 'edit' && !user_access('administer nodes')) {
// If a user is about to update a book page, we overload some
@ -166,14 +167,14 @@ function book_load($node) {
* Implementation of hook_insert().
*/
function book_insert($node) {
db_query("INSERT INTO {book} (nid, format, parent, weight, log) VALUES (%d, %d, %d, %d, '%s')", $node->nid, $node->format, $node->parent, $node->weight, $node->log);
db_query("INSERT INTO {book} (nid, parent, weight, log) VALUES (%d, %d, %d, '%s')", $node->nid, $node->parent, $node->weight, $node->log);
}
/**
* Implementation of hook_update().
*/
function book_update($node) {
db_query("UPDATE {book} SET format = %d, parent = %d, weight = %d, log = '%s' WHERE nid = %d", $node->format, $node->parent, $node->weight, $node->log, $node->nid);
db_query("UPDATE {book} SET parent = %d, weight = %d, log = '%s' WHERE nid = %d", $node->parent, $node->weight, $node->log, $node->nid);
}
/**
@ -187,17 +188,8 @@ function book_delete(&$node) {
* Implementation of hook_validate().
*/
function book_validate(&$node) {
if ($node->format && user_access('create php content')) {
// Do not filter PHP code. Do not auto-extract a teaser.
$node->teaser = $node->body;
}
else {
$node->format = 0;
}
// Set default values for non-administrators.
if (!user_access('administer nodes')) {
$node->format = 0;
$node->weight = 0;
$node->revision = 1;
}
@ -216,14 +208,11 @@ function book_form(&$node) {
$output .= implode('', taxonomy_node_form('book', $node));
}
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, filter_tips_short(), NULL, TRUE);
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, '', NULL, TRUE);
$output .= form_textarea(t('Log message'), 'log', $node->log, 60, 5, t('An explanation of the additions or updates being made to help the group understand your motivations.'));
if (user_access('administer nodes')) {
$output .= form_weight(t('Weight'), 'weight', $node->weight, 15, t('The heavier pages will sink and the lighter pages will be positioned nearer the top.'));
if (user_access('create php content')) {
$output .= form_radios(t('Type'), 'format', $node->format, array(0 => 'HTML / text', 1 => 'PHP'));
}
}
else {
// If a regular user updates a book page, we create a new revision
@ -401,24 +390,8 @@ function book_content($node, $teaser = FALSE) {
}
}
// Extract the page body. If body is dynamic (using PHP code), the body
// will be generated.
if ($node->format == 1) {
// Make sure only authorized users can preview PHP pages.
if ($op == t('Preview') && !user_access('create php content')) {
return;
}
ob_start();
eval($node->body);
$node->body = ob_get_contents();
ob_end_clean();
$node->teaser = node_teaser($node->body);
$node->readmore = (strlen($node->teaser) < strlen($node->body));
}
else {
$node = node_prepare($node, $teaser);
}
// Extract the page body.
$node = node_prepare($node, $teaser);
return $node;
}

View File

@ -39,10 +39,11 @@ function book_access($op, $node) {
// Only registered users can update book pages. Given the nature
// of the book module this is considered to be a good/safe idea.
// One can only update a book page if there are no suggested updates
// of that page waiting for approval, it is not a PHP page, and
// the "create new revision" bit is set. That is, only updates that
// don't overwrite the current or pending information are allowed.
return user_access('maintain books') && !$node->moderate && !$node->format && $node->revision;
// of that page waiting for approval and as long as the "create new
// revision"-bit is set. That is, only updates that don't overwrite
// the current or pending information are allowed.
return user_access('maintain books') && !$node->moderate && $node->revision;
}
}
@ -139,7 +140,7 @@ function book_block($op = 'list', $delta = 0) {
function book_load($node) {
global $user;
$book = db_fetch_object(db_query('SELECT format, parent, weight, log FROM {book} WHERE nid = %d', $node->nid));
$book = db_fetch_object(db_query('SELECT parent, weight, log FROM {book} WHERE nid = %d', $node->nid));
if (arg(1) == 'edit' && !user_access('administer nodes')) {
// If a user is about to update a book page, we overload some
@ -166,14 +167,14 @@ function book_load($node) {
* Implementation of hook_insert().
*/
function book_insert($node) {
db_query("INSERT INTO {book} (nid, format, parent, weight, log) VALUES (%d, %d, %d, %d, '%s')", $node->nid, $node->format, $node->parent, $node->weight, $node->log);
db_query("INSERT INTO {book} (nid, parent, weight, log) VALUES (%d, %d, %d, '%s')", $node->nid, $node->parent, $node->weight, $node->log);
}
/**
* Implementation of hook_update().
*/
function book_update($node) {
db_query("UPDATE {book} SET format = %d, parent = %d, weight = %d, log = '%s' WHERE nid = %d", $node->format, $node->parent, $node->weight, $node->log, $node->nid);
db_query("UPDATE {book} SET parent = %d, weight = %d, log = '%s' WHERE nid = %d", $node->parent, $node->weight, $node->log, $node->nid);
}
/**
@ -187,17 +188,8 @@ function book_delete(&$node) {
* Implementation of hook_validate().
*/
function book_validate(&$node) {
if ($node->format && user_access('create php content')) {
// Do not filter PHP code. Do not auto-extract a teaser.
$node->teaser = $node->body;
}
else {
$node->format = 0;
}
// Set default values for non-administrators.
if (!user_access('administer nodes')) {
$node->format = 0;
$node->weight = 0;
$node->revision = 1;
}
@ -216,14 +208,11 @@ function book_form(&$node) {
$output .= implode('', taxonomy_node_form('book', $node));
}
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, filter_tips_short(), NULL, TRUE);
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, '', NULL, TRUE);
$output .= form_textarea(t('Log message'), 'log', $node->log, 60, 5, t('An explanation of the additions or updates being made to help the group understand your motivations.'));
if (user_access('administer nodes')) {
$output .= form_weight(t('Weight'), 'weight', $node->weight, 15, t('The heavier pages will sink and the lighter pages will be positioned nearer the top.'));
if (user_access('create php content')) {
$output .= form_radios(t('Type'), 'format', $node->format, array(0 => 'HTML / text', 1 => 'PHP'));
}
}
else {
// If a regular user updates a book page, we create a new revision
@ -401,24 +390,8 @@ function book_content($node, $teaser = FALSE) {
}
}
// Extract the page body. If body is dynamic (using PHP code), the body
// will be generated.
if ($node->format == 1) {
// Make sure only authorized users can preview PHP pages.
if ($op == t('Preview') && !user_access('create php content')) {
return;
}
ob_start();
eval($node->body);
$node->body = ob_get_contents();
ob_end_clean();
$node->teaser = node_teaser($node->body);
$node->readmore = (strlen($node->teaser) < strlen($node->body));
}
else {
$node = node_prepare($node, $teaser);
}
// Extract the page body.
$node = node_prepare($node, $teaser);
return $node;
}

View File

@ -319,7 +319,7 @@ function comment_update_index() {
function comment_user($type, $edit, &$user, $category = NULL) {
if ($type == 'form' && $category == 'account') {
// when user tries to edit his own data
return array(array('title' => t('Comment settings'), 'data' => form_textarea(t('Signature'), 'signature', $user->signature, 64, 3, t('Your signature will be publicly displayed at the end of your comments.') .'<br />'. filter_tips_short()), 'weight' => 2));
return array(array('title' => t('Comment settings'), 'data' => form_textarea(t('Signature'), 'signature', $user->signature, 64, 3, t('Your signature will be publicly displayed at the end of your comments.')), 'weight' => 2));
}
if ($type == 'validate') {
// validate user data editing
@ -455,6 +455,13 @@ function comment_validate_form($edit) {
form_set_error('comment', t('The body of your comment is empty.'));
}
/*
** Validate filter format
*/
if (!filter_access($edit['format'])) {
form_set_error('format', t('The supplied input format is invalid.'));
}
/*
** Check validity of name, mail and homepage (if given)
*/
@ -953,7 +960,7 @@ function comment_admin_edit($cid) {
if ($comment) {
$form .= form_item(t('Author'), format_name($comment));
$form .= form_textfield(t('Subject'), 'subject', $comment->subject, 70, 128);
$form .= form_textarea(t('Comment'), 'comment', $comment->comment, 70, 15, filter_tips_short());
$form .= form_textarea(t('Comment'), 'comment', $comment->comment, 70, 15, '');
$form .= form_radios(t('Status'), 'status', $comment->status, array('published', 'not published'));
$form .= form_hidden('cid', $cid);
$form .= form_submit(t('Submit'));
@ -986,7 +993,7 @@ function comment_delete($cid) {
// Print a confirmation.
else if ($comment->cid) {
drupal_set_message(t('do you want to delete this comment and all its replies?'));
$comment->comment = check_output($comment->comment);
$comment->comment = check_output($comment->comment, $comment->format);
$output = theme('comment', $comment);
$output .= form_submit(t('Delete comment'));
}
@ -1406,8 +1413,11 @@ function theme_comment_form($edit, $title) {
$form .= form_textfield(t('Subject'), 'subject', $edit['subject'], 50, 64);
}
// format selector
$form .= filter_form('format', $edit['format']);
// comment field:
$form .= form_textarea(t('Comment'), 'comment', $edit['comment'] ? $edit['comment'] : $user->signature, 70, 10, filter_tips_short(), NULL, TRUE);
$form .= form_textarea(t('Comment'), 'comment', $edit['comment'] ? $edit['comment'] : $user->signature, 70, 10, '', NULL, TRUE);
// preview button:
$form .= form_hidden('cid', $edit['cid']);
@ -1438,7 +1448,7 @@ function theme_comment_view($comment, $links = '', $visible = 1) {
// Switch to folded/unfolded view of the comment
if ($visible) {
$comment->comment = check_output($comment->comment);
$comment->comment = check_output($comment->comment, $comment->format);
$output .= theme('comment', $comment, $links);
}
else {

View File

@ -319,7 +319,7 @@ function comment_update_index() {
function comment_user($type, $edit, &$user, $category = NULL) {
if ($type == 'form' && $category == 'account') {
// when user tries to edit his own data
return array(array('title' => t('Comment settings'), 'data' => form_textarea(t('Signature'), 'signature', $user->signature, 64, 3, t('Your signature will be publicly displayed at the end of your comments.') .'<br />'. filter_tips_short()), 'weight' => 2));
return array(array('title' => t('Comment settings'), 'data' => form_textarea(t('Signature'), 'signature', $user->signature, 64, 3, t('Your signature will be publicly displayed at the end of your comments.')), 'weight' => 2));
}
if ($type == 'validate') {
// validate user data editing
@ -455,6 +455,13 @@ function comment_validate_form($edit) {
form_set_error('comment', t('The body of your comment is empty.'));
}
/*
** Validate filter format
*/
if (!filter_access($edit['format'])) {
form_set_error('format', t('The supplied input format is invalid.'));
}
/*
** Check validity of name, mail and homepage (if given)
*/
@ -953,7 +960,7 @@ function comment_admin_edit($cid) {
if ($comment) {
$form .= form_item(t('Author'), format_name($comment));
$form .= form_textfield(t('Subject'), 'subject', $comment->subject, 70, 128);
$form .= form_textarea(t('Comment'), 'comment', $comment->comment, 70, 15, filter_tips_short());
$form .= form_textarea(t('Comment'), 'comment', $comment->comment, 70, 15, '');
$form .= form_radios(t('Status'), 'status', $comment->status, array('published', 'not published'));
$form .= form_hidden('cid', $cid);
$form .= form_submit(t('Submit'));
@ -986,7 +993,7 @@ function comment_delete($cid) {
// Print a confirmation.
else if ($comment->cid) {
drupal_set_message(t('do you want to delete this comment and all its replies?'));
$comment->comment = check_output($comment->comment);
$comment->comment = check_output($comment->comment, $comment->format);
$output = theme('comment', $comment);
$output .= form_submit(t('Delete comment'));
}
@ -1406,8 +1413,11 @@ function theme_comment_form($edit, $title) {
$form .= form_textfield(t('Subject'), 'subject', $edit['subject'], 50, 64);
}
// format selector
$form .= filter_form('format', $edit['format']);
// comment field:
$form .= form_textarea(t('Comment'), 'comment', $edit['comment'] ? $edit['comment'] : $user->signature, 70, 10, filter_tips_short(), NULL, TRUE);
$form .= form_textarea(t('Comment'), 'comment', $edit['comment'] ? $edit['comment'] : $user->signature, 70, 10, '', NULL, TRUE);
// preview button:
$form .= form_hidden('cid', $edit['cid']);
@ -1438,7 +1448,7 @@ function theme_comment_view($comment, $links = '', $visible = 1) {
// Switch to folded/unfolded view of the comment
if ($visible) {
$comment->comment = check_output($comment->comment);
$comment->comment = check_output($comment->comment, $comment->format);
$output .= theme('comment', $comment, $links);
}
else {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -268,7 +268,7 @@ function forum_form(&$node) {
$output .= form_checkbox(t('Leave shadow copy'), 'shadow', 1, $node->shadow, t('If you move this topic, you can leave a link in the old forum to the new forum.'));
}
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 10, filter_tips_short());
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 10, '');
return $output;
}

View File

@ -268,7 +268,7 @@ function forum_form(&$node) {
$output .= form_checkbox(t('Leave shadow copy'), 'shadow', 1, $node->shadow, t('If you move this topic, you can leave a link in the old forum to the new forum.'));
}
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 10, filter_tips_short());
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 10, '');
return $output;
}

View File

@ -168,6 +168,11 @@ function node_teaser($body) {
return $body;
}
// If the body contains PHP code, do not split it up to prevent parse errors.
if (strpos($body, '<?') != false) {
return $body;
}
// If a valid delimiter has been specified, use it to chop of the teaser.
if ($delimiter > 0) {
return substr($body, 0, $delimiter);
@ -511,10 +516,10 @@ function node_view($node, $teaser = FALSE, $page = FALSE) {
function node_prepare($node, $teaser = FALSE) {
$node->readmore = (strlen($node->teaser) < strlen($node->body));
if ($teaser == FALSE) {
$node->body = check_output($node->body);
$node->body = check_output($node->body, $node->format);
}
else {
$node->teaser = check_output($node->teaser);
$node->teaser = check_output($node->teaser, $node->format);
}
return $node;
}
@ -999,7 +1004,7 @@ function node_feed($nodes = 0, $channel = array()) {
// Load the specified node:
$item = node_load(array('nid' => $node->nid));
$link = url("node/$node->nid", NULL, NULL, 1);
$items .= format_rss_item($item->title, $link, ($item->teaser ? $item->teaser : $item->body), array('pubDate' => date('r', $item->changed)));
$items .= format_rss_item($item->title, $link, check_output($item->teaser ? $item->teaser : $item->body, $item->format), array('pubDate' => date('r', $item->changed)));
}
$channel_defaults = array(
@ -1096,6 +1101,11 @@ function node_validate($node) {
node_invoke($node, 'validate');
node_invoke_nodeapi($node, 'validate');
// Check input format access
if (!filter_access($node->format)) {
form_set_error('format', t('The supplied input format is invalid.'));
}
$node->validated = TRUE;
return $node;
@ -1156,6 +1166,10 @@ function node_form($edit) {
$output .= '<div class="standard">';
$output .= form_textfield(t('Title'), 'title', $edit->title, 60, 128, NULL, NULL, TRUE);
// Add filter format selector / filter tips
$output .= filter_form('format', $edit->format);
// Add the node-type-specific fields.
$output .= $form;
@ -1516,7 +1530,7 @@ function node_nodeapi(&$node, $op, $arg = 0) {
$output[t('revision')] = form_checkbox('', "node_revision_$node->type", 1, variable_get("node_revision_$node->type", 0));
return $output;
case 'fields':
return array('nid', 'uid', 'type', 'title', 'teaser', 'body', 'revisions', 'status', 'promote', 'moderate', 'sticky', 'created', 'changed');
return array('nid', 'uid', 'type', 'title', 'teaser', 'body', 'revisions', 'status', 'promote', 'moderate', 'sticky', 'created', 'changed', 'format');
}
}
@ -1568,13 +1582,18 @@ function node_nodeapi(&$node, $op, $arg = 0) {
* TRUE if the operation may be performed.
*/
function node_access($op, $node = NULL) {
// Convert the node to an object if necessary:
$node = array2object($node);
// If the node is in a restricted format, disallow editing.
if ($op == 'update' && !filter_access($node->format)) {
return FALSE;
}
if (user_access('administer nodes')) {
return TRUE;
}
// Convert the node to an object if necessary:
$node = array2object($node);
// Can't use node_invoke(), because the access hook takes the $op parameter
// before the $node parameter.
$access = module_invoke(node_get_module_name($node), 'access', $op, $node);

View File

@ -168,6 +168,11 @@ function node_teaser($body) {
return $body;
}
// If the body contains PHP code, do not split it up to prevent parse errors.
if (strpos($body, '<?') != false) {
return $body;
}
// If a valid delimiter has been specified, use it to chop of the teaser.
if ($delimiter > 0) {
return substr($body, 0, $delimiter);
@ -511,10 +516,10 @@ function node_view($node, $teaser = FALSE, $page = FALSE) {
function node_prepare($node, $teaser = FALSE) {
$node->readmore = (strlen($node->teaser) < strlen($node->body));
if ($teaser == FALSE) {
$node->body = check_output($node->body);
$node->body = check_output($node->body, $node->format);
}
else {
$node->teaser = check_output($node->teaser);
$node->teaser = check_output($node->teaser, $node->format);
}
return $node;
}
@ -999,7 +1004,7 @@ function node_feed($nodes = 0, $channel = array()) {
// Load the specified node:
$item = node_load(array('nid' => $node->nid));
$link = url("node/$node->nid", NULL, NULL, 1);
$items .= format_rss_item($item->title, $link, ($item->teaser ? $item->teaser : $item->body), array('pubDate' => date('r', $item->changed)));
$items .= format_rss_item($item->title, $link, check_output($item->teaser ? $item->teaser : $item->body, $item->format), array('pubDate' => date('r', $item->changed)));
}
$channel_defaults = array(
@ -1096,6 +1101,11 @@ function node_validate($node) {
node_invoke($node, 'validate');
node_invoke_nodeapi($node, 'validate');
// Check input format access
if (!filter_access($node->format)) {
form_set_error('format', t('The supplied input format is invalid.'));
}
$node->validated = TRUE;
return $node;
@ -1156,6 +1166,10 @@ function node_form($edit) {
$output .= '<div class="standard">';
$output .= form_textfield(t('Title'), 'title', $edit->title, 60, 128, NULL, NULL, TRUE);
// Add filter format selector / filter tips
$output .= filter_form('format', $edit->format);
// Add the node-type-specific fields.
$output .= $form;
@ -1516,7 +1530,7 @@ function node_nodeapi(&$node, $op, $arg = 0) {
$output[t('revision')] = form_checkbox('', "node_revision_$node->type", 1, variable_get("node_revision_$node->type", 0));
return $output;
case 'fields':
return array('nid', 'uid', 'type', 'title', 'teaser', 'body', 'revisions', 'status', 'promote', 'moderate', 'sticky', 'created', 'changed');
return array('nid', 'uid', 'type', 'title', 'teaser', 'body', 'revisions', 'status', 'promote', 'moderate', 'sticky', 'created', 'changed', 'format');
}
}
@ -1568,13 +1582,18 @@ function node_nodeapi(&$node, $op, $arg = 0) {
* TRUE if the operation may be performed.
*/
function node_access($op, $node = NULL) {
// Convert the node to an object if necessary:
$node = array2object($node);
// If the node is in a restricted format, disallow editing.
if ($op == 'update' && !filter_access($node->format)) {
return FALSE;
}
if (user_access('administer nodes')) {
return TRUE;
}
// Convert the node to an object if necessary:
$node = array2object($node);
// Can't use node_invoke(), because the access hook takes the $op parameter
// before the $node parameter.
$access = module_invoke(node_get_module_name($node), 'access', $op, $node);

View File

@ -9,7 +9,6 @@ function page_help($section) {
case 'admin/help#page':
return t("
<p>The page module is used when you want to create content that optionally inserts a link into your navigation system. You can also, however, create pages that don't have this link by skipping the link text field in the page form. At this time, not all themes support the link insertion behavior. Some themes, like xtemplate, provide alternative mechanisms for link creation. Pages are also unique in that they shortcut the typical lifecycle of user generated content (i.e. submit -&gt; moderate -&gt; post -&gt; comment). </p>
<p>If you enable the <strong>create PHP content</strong> permission for a role, pages may consist of PHP code in addition to HTML and text.</p>
<h3>User access permissions for pages</h3>
<p><strong>create pages:</strong> Allows a role to create pages. They cannot edit or delete pages, even if they are the authors. You must enable this permission to in order for a role to create a page.</p>
<p><strong>edit own pages:</strong> Allows a role to add/edit pages if they own the page. Use this permission if you want users to be able to edit and maintain their own pages.</p>
@ -56,14 +55,14 @@ function page_access($op, $node) {
* Implementation of hook_insert().
*/
function page_insert($node) {
db_query("INSERT INTO {page} (nid, format, link, description) VALUES (%d, %d, '%s', '%s')", $node->nid, $node->format, $node->link, $node->description);
db_query("INSERT INTO {page} (nid, link, description) VALUES (%d, '%s', '%s')", $node->nid, $node->link, $node->description);
}
/**
* Implementation of hook_update().
*/
function page_update($node) {
db_query("UPDATE {page} SET format = %d, link = '%s', description = '%s' WHERE nid = %d", $node->format, $node->link, $node->description, $node->nid);
db_query("UPDATE {page} SET link = '%s', description = '%s' WHERE nid = %d", $node->link, $node->description, $node->nid);
}
/**
@ -77,7 +76,7 @@ function page_delete(&$node) {
* Implementation of hook_load().
*/
function page_load($node) {
return db_fetch_object(db_query('SELECT format, link, description FROM {page} WHERE nid = %d', $node->nid));
return db_fetch_object(db_query('SELECT link, description FROM {page} WHERE nid = %d', $node->nid));
}
/**
@ -92,23 +91,9 @@ function page_menu() {
/**
* Implementation of hook_content().
*
* If body is dynamic (using PHP code), the body will be generated.
*/
function page_content($node, $teaser = FALSE) {
if ($node->format == 1) {
// PHP type
ob_start();
eval($node->body);
$node->body = ob_get_contents();
ob_end_clean();
$node->teaser = node_teaser($node->body);
$node->readmore = (strlen($node->teaser) < strlen($node->body));
}
else {
// Assume HTML type by default
$node = node_prepare($node, $teaser);
}
$node = node_prepare($node, $teaser);
return $node;
}
@ -128,38 +113,12 @@ function page_form(&$node) {
$output .= implode('', taxonomy_node_form('page', $node));
}
if (($node->format == 1) && (!user_access('create php content'))) {
drupal_set_message(t('the body contents of this page are written in PHP and you do not have sufficient permissions to make changes to the body. You can edit the other elements of the page.'));
$output .= form_hidden('format', $node->format);
$hide_types = true;
}
else {
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, filter_tips_short(), NULL, TRUE);
}
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, '', NULL, TRUE);
$output .= form_textfield(t('Link name'), 'link', $node->link, 60, 64, t('To make the page show up in the navigation links, enter the name of the link. Otherwise, leave this blank.'));
$output .= form_textfield(t('Link description'), 'description', $node->description, 60, 64, t("The description displayed when hovering over the page's link. Leave blank when you don't want a description."));
$content_type = (user_access('create php content')) ? array(0 => 'HTML', 1 => 'PHP') : false;
if (!$hide_types && $content_type) {
$output .= form_radios(t('Type'), 'format', $node->format, $content_type);
}
return $output;
}
/**
* Implementation of hook_validate().
*/
function page_validate(&$node) {
if ($node->format && user_access('create php content')) {
// Do not filter PHP code, do not auto-extract a teaser
$node->teaser = $node->body;
}
if (($node->format == 1) && (!user_access('create php content'))) {
/* Overwrite the submitted node body since they don't have sufficient privileges. */
$node->body = db_result(db_query('SELECT body FROM {node} WHERE nid = %d', $node->nid));
}
}
?>

View File

@ -9,7 +9,6 @@ function page_help($section) {
case 'admin/help#page':
return t("
<p>The page module is used when you want to create content that optionally inserts a link into your navigation system. You can also, however, create pages that don't have this link by skipping the link text field in the page form. At this time, not all themes support the link insertion behavior. Some themes, like xtemplate, provide alternative mechanisms for link creation. Pages are also unique in that they shortcut the typical lifecycle of user generated content (i.e. submit -&gt; moderate -&gt; post -&gt; comment). </p>
<p>If you enable the <strong>create PHP content</strong> permission for a role, pages may consist of PHP code in addition to HTML and text.</p>
<h3>User access permissions for pages</h3>
<p><strong>create pages:</strong> Allows a role to create pages. They cannot edit or delete pages, even if they are the authors. You must enable this permission to in order for a role to create a page.</p>
<p><strong>edit own pages:</strong> Allows a role to add/edit pages if they own the page. Use this permission if you want users to be able to edit and maintain their own pages.</p>
@ -56,14 +55,14 @@ function page_access($op, $node) {
* Implementation of hook_insert().
*/
function page_insert($node) {
db_query("INSERT INTO {page} (nid, format, link, description) VALUES (%d, %d, '%s', '%s')", $node->nid, $node->format, $node->link, $node->description);
db_query("INSERT INTO {page} (nid, link, description) VALUES (%d, '%s', '%s')", $node->nid, $node->link, $node->description);
}
/**
* Implementation of hook_update().
*/
function page_update($node) {
db_query("UPDATE {page} SET format = %d, link = '%s', description = '%s' WHERE nid = %d", $node->format, $node->link, $node->description, $node->nid);
db_query("UPDATE {page} SET link = '%s', description = '%s' WHERE nid = %d", $node->link, $node->description, $node->nid);
}
/**
@ -77,7 +76,7 @@ function page_delete(&$node) {
* Implementation of hook_load().
*/
function page_load($node) {
return db_fetch_object(db_query('SELECT format, link, description FROM {page} WHERE nid = %d', $node->nid));
return db_fetch_object(db_query('SELECT link, description FROM {page} WHERE nid = %d', $node->nid));
}
/**
@ -92,23 +91,9 @@ function page_menu() {
/**
* Implementation of hook_content().
*
* If body is dynamic (using PHP code), the body will be generated.
*/
function page_content($node, $teaser = FALSE) {
if ($node->format == 1) {
// PHP type
ob_start();
eval($node->body);
$node->body = ob_get_contents();
ob_end_clean();
$node->teaser = node_teaser($node->body);
$node->readmore = (strlen($node->teaser) < strlen($node->body));
}
else {
// Assume HTML type by default
$node = node_prepare($node, $teaser);
}
$node = node_prepare($node, $teaser);
return $node;
}
@ -128,38 +113,12 @@ function page_form(&$node) {
$output .= implode('', taxonomy_node_form('page', $node));
}
if (($node->format == 1) && (!user_access('create php content'))) {
drupal_set_message(t('the body contents of this page are written in PHP and you do not have sufficient permissions to make changes to the body. You can edit the other elements of the page.'));
$output .= form_hidden('format', $node->format);
$hide_types = true;
}
else {
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, filter_tips_short(), NULL, TRUE);
}
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, '', NULL, TRUE);
$output .= form_textfield(t('Link name'), 'link', $node->link, 60, 64, t('To make the page show up in the navigation links, enter the name of the link. Otherwise, leave this blank.'));
$output .= form_textfield(t('Link description'), 'description', $node->description, 60, 64, t("The description displayed when hovering over the page's link. Leave blank when you don't want a description."));
$content_type = (user_access('create php content')) ? array(0 => 'HTML', 1 => 'PHP') : false;
if (!$hide_types && $content_type) {
$output .= form_radios(t('Type'), 'format', $node->format, $content_type);
}
return $output;
}
/**
* Implementation of hook_validate().
*/
function page_validate(&$node) {
if ($node->format && user_access('create php content')) {
// Do not filter PHP code, do not auto-extract a teaser
$node->teaser = $node->body;
}
if (($node->format == 1) && (!user_access('create php content'))) {
/* Overwrite the submitted node body since they don't have sufficient privileges. */
$node->body = db_result(db_query('SELECT body FROM {node} WHERE nid = %d', $node->nid));
}
}
?>

View File

@ -619,7 +619,7 @@ function statistics_summary($dbfield, $dbrows) {
$links = link_node($content, 1);
$output .= '<tr><td><strong>'. l($nid['title'], 'node/'. $nid['nid'], array('title' => t('View this posting.'))) .'</strong></td><td style="text-align: right;"><small>'. t('Submitted by %a on %b', array('%a' => format_name($content), '%b' => format_date($content->created, 'large'))) .'</small></td></tr>';
$output .= '<tr><td colspan="2"><div style="margin-left: 20px;">'. check_output($content->teaser) .'</div></td></tr>';
$output .= '<tr><td colspan="2"><div style="margin-left: 20px;">'. check_output($content->teaser, $content->format) .'</div></td></tr>';
$output .= '<tr><td style="text-align: right;" colspan="2">[ '. theme('links', $links) .' ]<br /><br /></td></tr>';
}

View File

@ -619,7 +619,7 @@ function statistics_summary($dbfield, $dbrows) {
$links = link_node($content, 1);
$output .= '<tr><td><strong>'. l($nid['title'], 'node/'. $nid['nid'], array('title' => t('View this posting.'))) .'</strong></td><td style="text-align: right;"><small>'. t('Submitted by %a on %b', array('%a' => format_name($content), '%b' => format_date($content->created, 'large'))) .'</small></td></tr>';
$output .= '<tr><td colspan="2"><div style="margin-left: 20px;">'. check_output($content->teaser) .'</div></td></tr>';
$output .= '<tr><td colspan="2"><div style="margin-left: 20px;">'. check_output($content->teaser, $content->format) .'</div></td></tr>';
$output .= '<tr><td style="text-align: right;" colspan="2">[ '. theme('links', $links) .' ]<br /><br /></td></tr>';
}

View File

@ -113,7 +113,7 @@ function story_form(&$node) {
$output .= implode('', taxonomy_node_form('story', $node));
}
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 15, filter_tips_short(), NULL, TRUE);
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 15, '', NULL, TRUE);
return $output;
}

View File

@ -113,7 +113,7 @@ function story_form(&$node) {
$output .= implode('', taxonomy_node_form('story', $node));
}
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 15, filter_tips_short(), NULL, TRUE);
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 15, '', NULL, TRUE);
return $output;
}

View File

@ -43,7 +43,7 @@ function system_help_page() {
* Implementation of hook_perm().
*/
function system_perm() {
return array('administer site configuration', 'access administration pages', 'bypass input data check', 'create php content');
return array('administer site configuration', 'access administration pages', 'bypass input data check');
}
/**

View File

@ -43,7 +43,7 @@ function system_help_page() {
* Implementation of hook_perm().
*/
function system_perm() {
return array('administer site configuration', 'access administration pages', 'bypass input data check', 'create php content');
return array('administer site configuration', 'access administration pages', 'bypass input data check');
}
/**