View source
<?php
if (module_exists('views')) {
include "quotes_views.inc";
}
define('QUOTES_VERSION', '$Id$');
define('BIOS_PATH', 'admin/settings/quotes/bios');
function quotes_perm() {
return array(
'access quotes',
'administer quotes',
'create quotes',
'import quotes',
'edit own quotes',
'promote quotes to block',
'view my quotes',
);
}
function quotes_access($op, $node) {
global $user;
switch ($op) {
case 'create':
return user_access('create quotes') || user_access('import quotes') || user_access('edit own quotes');
case 'update':
case 'delete':
if (user_access('edit own quotes') && $user->uid == $node->uid) {
return TRUE;
}
if (user_access('administer quotes')) {
return TRUE;
}
return;
case 'view':
if (user_access('access quotes')) {
return TRUE;
}
return;
}
}
function quotes_menu($may_cache) {
global $user;
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'node/add/quotes',
'title' => t('Quotes'),
'access' => user_access('create quotes') || user_access('import quotes') || user_access('edit own quotes'),
);
$items[] = array(
'path' => 'node/add/quotes/add',
'title' => t('Add'),
'access' => user_access('create quotes') || user_access('edit own quotes'),
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items[] = array(
'path' => 'node/add/quotes/import',
'title' => t('Import'),
'access' => user_access('import quotes'),
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'quotes',
'title' => t('Quotes'),
'access' => user_access('access content'),
'callback' => '_quotes_page',
'type' => MENU_SUGGESTED_ITEM,
);
$items[] = array(
'path' => 'quotes/author',
'title' => t('Quotes by author'),
'access' => user_access('access content'),
'callback' => 'quotes_author',
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'quotes/feed',
'title' => t('RSS feed'),
'access' => user_access('access content'),
'callback' => '_quotes_feed_last',
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'quotes/autocomplete/author',
'title' => 'Autocomplete Author Field',
'access' => user_access('access quotes'),
'callback' => '_quotes_autocomplete_author',
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'quotes/autocomplete/citation',
'title' => 'Autocomplete Citation Field',
'access' => user_access('access quotes'),
'callback' => '_quotes_autocomplete_citation',
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/settings/quotes',
'title' => t('Quotes'),
'description' => t('Configure Quotes module options and blocks.'),
'access' => user_access('administer quotes'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'_quotes_admin_settings',
),
);
$items[] = array(
'path' => 'admin/settings/quotes/general',
'title' => t('General'),
'access' => user_access('administer quotes'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -1,
);
$items[] = array(
'path' => 'admin/settings/quotes/blocks',
'title' => t('Configure blocks'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'_quotes_blocks',
),
'access' => user_access('administer quotes'),
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/settings/quotes/export',
'title' => t('Export'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'quotes_export',
),
'access' => user_access('administer quotes'),
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => BIOS_PATH,
'title' => t('Bios'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'quotes_bios',
),
'access' => user_access('administer quotes'),
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/settings/quotes/delete',
'title' => t('Delete quote block'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'_quotes_block_delete',
),
'type' => MENU_CALLBACK,
);
}
else {
drupal_add_css(drupal_get_path('module', 'quotes') . '/quotes.css');
if (arg(0) == 'user' && is_numeric(arg(1))) {
include drupal_get_path('module', 'quotes') . '/quotes.user.inc';
$items[] = array(
'path' => 'user/' . arg(1) . '/quotes',
'title' => 'My Quotes',
'callback' => 'quotes_user_page',
'callback arguments' => array(
arg(1),
),
'access' => user_access('view my quotes'),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
}
$items[] = array(
'path' => "quotes/{$user->uid}",
'title' => t('My quotes'),
'access' => $user->uid && (user_access('create quotes') || user_access('import quotes') || user_access('edit own quotes')),
'type' => variable_get('quotes_show_myquotes', TRUE) ? MENU_NORMAL_ITEM : MENU_CALLBACK,
);
}
return $items;
}
function quotes_node_info() {
return array(
'quotes' => array(
'name' => t('Quotes'),
'module' => 'quotes',
'description' => t('A quote is a famous, infamous, humorous, witty, or otherwise noteworthy quotation or fortune file entry. Users can maintain personal lists of quotations and display quotes in one or more blocks. Quotes can be entered one at a time or mass imported in either tab-separated text or fortune file format.'),
),
);
}
function _quotes_autocomplete_author($string) {
$matches = array();
$result = db_query("SELECT name FROM {quotes_authors} WHERE LOWER(name) LIKE LOWER('%%%s%%')", $string);
while ($row = db_fetch_object($result)) {
$matches[$row->name] = check_plain($row->name);
}
print drupal_to_js($matches);
}
function _quotes_autocomplete_citation($string) {
$matches = array();
$result = db_query("SELECT citation FROM {quotes} WHERE LOWER(citation) LIKE LOWER('%%%s%%')", $string);
while ($row = db_fetch_object($result)) {
$matches[$row->citation] = check_plain($row->citation);
}
print drupal_to_js($matches);
}
function quotes_form(&$node, &$param) {
global $_quotes_importing;
$form = array(
'quotes_data' => array(),
);
if ($_quotes_importing || arg(3) != 'import') {
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#required' => FALSE,
'#default_value' => $node->title,
'#description' => t('Enter the title for this quote. If you include the variable %id, it will be replaced by the newly created quote\'s node ID.', array(
'%id' => '%id',
)),
'#weight' => -10,
);
$form['quotes_data']['body'] = array(
'#type' => 'textarea',
'#title' => t('Quote'),
'#required' => TRUE,
'#default_value' => $node->body,
);
$form['quotes_data']['quotes_author'] = array(
'#type' => 'textfield',
'#title' => t('Author'),
'#autocomplete_path' => 'quotes/autocomplete/author',
'#rows' => 1,
'#maxlength' => 1023,
'#default_value' => $node->quotes_author,
);
$form['quotes_data']['quotes_citation'] = array(
'#type' => 'textfield',
'#title' => t('Citation'),
'#autocomplete_path' => 'quotes/autocomplete/citation',
'#rows' => 1,
'#default_value' => $node->quotes_citation,
);
}
else {
if (!user_access('import quotes')) {
drupal_access_denied();
}
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#required' => FALSE,
'#default_value' => $node->title,
'#description' => t('Enter the title that will be used for all imported quotes. If you include the variable %id, it will be replaced by the newly created quote\'s node ID.', array(
'%id' => '%id',
)),
'#weight' => -10,
);
$form['quotes_data']['quotes_format'] = array(
'#type' => 'radios',
'#title' => t('Format'),
'#required' => TRUE,
'#default_value' => $node->quotes_format ? $node->quotes_format : 'text',
'#options' => array(
'text' => t('Tab-separated text'),
'fortune' => t('Fortune file'),
),
);
$form['quotes_data']['body'] = array(
'#type' => 'textarea',
'#title' => t('Quotes'),
'#required' => TRUE,
'#rows' => 20,
'#default_value' => $node->body,
);
}
if (user_access('promote quotes to block')) {
$form['quotes_data']['quotes_promote'] = array(
'#type' => 'checkbox',
'#title' => t('Display in quote blocks'),
'#default_value' => isset($node->quotes_promote) ? $node->quotes_promote : 1,
);
}
$form['quotes_data']['filter'] = filter_form($node->format);
return $form;
}
function quotes_validate(&$node) {
global $_quotes_importing;
if ($_quotes_importing || arg(3) != 'import') {
return;
}
_quotes_parse_import($node, TRUE);
}
function quotes_submit(&$node) {
global $_quotes_importing;
if ($_quotes_importing || arg(3) != 'import') {
return;
}
$_quotes_importing = TRUE;
$count = 0;
foreach (_quotes_parse_import($node, TRUE) as $quote) {
++$count;
$temp = $node;
$temp->body = $quote->body;
$temp->teaser = '';
$temp->quotes_author = $quote->quotes_author;
$temp->quotes_citation = $quote->quotes_citation;
drupal_execute('quotes_node_form', (array) $temp, array(
'type' => 'quotes',
));
if (form_get_errors()) {
form_set_error('body', t('Only the first !count quotes were imported.', array(
'!count' => $count,
)));
return;
}
}
$_quotes_importing = FALSE;
drupal_set_message(t('!count quotes imported.', array(
'!count' => $count,
)));
drupal_goto('quotes');
}
function quotes_load($node) {
$obj = db_fetch_object(db_query("SELECT a.aid AS quotes_aid, a.name AS quotes_author, a.bio AS quotes_bio, q.citation AS quotes_citation, q.promote AS quotes_promote FROM {quotes} q JOIN {quotes_authors} a USING (aid) WHERE q.vid = %d", $node->vid));
return $obj;
}
function quotes_insert($node) {
$aid = _quotes_handle_author($node->quotes_author);
db_query("INSERT INTO {quotes} (nid, vid, aid, citation, promote) VALUES (%d, %d, '%d', '%s', %d)", $node->nid, $node->vid, $aid, $node->quotes_citation, $node->quotes_promote);
if (strpos($node->title, '%id') !== FALSE) {
$node->title = str_replace('%id', $node->nid, $node->title);
db_query("UPDATE {node} SET title = '%s' WHERE vid = %d", $node->title, $node->vid);
db_query("UPDATE {node_revisions} SET title = '%s' WHERE vid = %d", $node->title, $node->vid);
}
}
function _quotes_handle_author($author) {
$aid = db_result(db_query("SELECT qa.aid FROM {quotes_authors} qa WHERE qa.name='%s'", $author));
if (empty($aid)) {
$result = db_query("INSERT INTO {quotes_authors} (name) VALUES ('%s')", $author);
if ($result === FALSE) {
drupal_set_message(t('Quotes: insert author failed.'), 'error');
}
$aid = db_result(db_query("SELECT aid FROM {quotes_authors} qa WHERE qa.name='%s'", $author));
if ($aid === FALSE) {
drupal_set_message(t('Quotes: get aid failed.'), 'error');
}
}
return $aid;
}
function quotes_update($node) {
global $user;
$aid = _quotes_handle_author($node->quotes_author);
if ($node->revision) {
quotes_insert($node);
}
else {
$result = db_query("UPDATE {quotes} q SET q.aid='%d', q.citation='%s', q.promote=%d WHERE q.nid=%d AND q.vid=%d", $aid, $node->quotes_citation, $node->quotes_promote, $node->nid, $node->vid);
if ($result === FALSE) {
drupal_set_message(t('Quotes update failed.'), 'error');
}
}
}
function quotes_delete($node) {
$aid = _quotes_handle_author($node->quotes_author);
$aid_count = db_result(db_query("SELECT COUNT(q.nid) FROM {quotes} q WHERE q.aid='%d'", $aid));
if ($aid_count == 1) {
db_query("DELETE FROM {quotes_authors} WHERE aid = %d", $aid);
}
db_query("DELETE FROM {quotes} WHERE nid = %d", $node->nid);
}
function quotes_view($node, $teaser = FALSE, $page = FALSE, $links = FALSE, $max_length = 0) {
global $user;
if ($page) {
$breadcrumb = array();
$breadcrumb[] = array(
'path' => 'quotes',
'title' => t('Quotes'),
);
$breadcrumb[] = array(
'path' => "quotes/{$node->uid}",
'title' => t("!name's quotes", array(
'!name' => $node->uid ? $node->name : variable_get('anonymous', t('Anonymous')),
)),
);
$breadcrumb[] = array(
'path' => "node/{$node->nid}",
);
menu_set_location($breadcrumb);
}
if (!isset($node->quotes_format)) {
$node = node_prepare($node);
$node->content['body'] = array(
'#value' => theme('quotes_quote', $node, $teaser, FALSE, $max_length),
'#weight' => 0,
);
}
else {
$quotes = array();
foreach (_quotes_parse_import($node) as $quote) {
$quote->body = check_markup($quote->body, $node->format, $user->uid == $node->uid);
$quotes[] = theme('quotes_quote', $quote);
}
$node->content['body'] = array(
'#value' => theme('item_list', $quotes, t('!count quotes will be imported:', array(
'!count' => count($quotes),
))),
'#weight' => 0,
);
}
return $node;
}
function quotes_link($type, $node = NULL, $teaser = FALSE) {
global $user;
$links = array();
if ($type == 'node' && $node->type == 'quotes' && !(arg(0) == 'quotes' && arg(1) == $node->uid)) {
$name = $node->uid ? $node->name : variable_get('anonymous', t('Anonymous'));
if (variable_get('quotes_showlink', TRUE)) {
if ($node->uid != $user->uid) {
$links['quotes_usernames_quotes'] = array(
'title' => t("!name's quotes", array(
'!name' => $name,
)),
'href' => "quotes/{$node->uid}",
'attributes' => array(
'title' => t("View !name's quotes.", array(
'!name' => $name,
)),
),
);
}
}
if (variable_get('quotes_edit_link', TRUE)) {
if (user_access('edit own quotes') && $node->uid == $user->uid || user_access('administer quotes')) {
$links['quotes_edit_link'] = array(
'title' => t('Edit quote'),
'href' => 'node/' . $node->nid . '/edit',
'attributes' => array(
'title' => t('Edit this quote'),
),
);
}
}
}
return $links;
}
function quotes_block($op = 'list', $delta = 0, $edit = array()) {
global $_quotes_subs;
$_quotes_subs = array(
'%' . t('interval') => NULL,
'%' . t('bid') => NULL,
'%' . t('title') => NULL,
'%' . t('nid') => NULL,
'%' . t('user') => NULL,
);
switch ($op) {
case 'mb_blocked':
return 'quotes';
case 'list':
$blocks = array();
$result = db_query('SELECT qb.bid, qb.name FROM {quotes_blocks} qb');
while ($block = db_fetch_object($result)) {
$blocks[$block->bid] = array(
'info' => t('Quotes') . ': ' . $block->name,
);
}
return $blocks;
case 'view':
$block = db_fetch_array(db_query('SELECT qb.* FROM {quotes_blocks} qb WHERE qb.bid=%d', $delta));
if (!$block) {
return NULL;
}
if ($block['cron_interval'] > 0) {
if (!$block['vid'] || $block['cron_last'] + $block['cron_interval'] * $block['cron_step'] < time()) {
$block['vid'] = quotes_get_quote($block, TRUE, 1);
db_query('UPDATE {quotes_blocks} SET vid=%d, cron_last=%d WHERE bid=%d', $block['vid'][0], time(), $delta);
cache_clear_all();
}
else {
$block['vid'] = array(
$block['vid'],
);
}
}
else {
$block['vid'] = quotes_get_quote($block, TRUE, $block['count']);
}
if (!$block['vid']) {
return NULL;
}
$view_text = $block['view_text'];
$link_weight = $block['view_weight'];
$more_text = $block['more_text'];
$rand_freq = $block['rand_freq'];
$output = NULL;
unset($blk_title);
foreach ($block['vid'] as $nid) {
$node = node_load($nid);
if (!isset($blk_title)) {
$blk_title = filter_xss($node->title);
$blk_nid = $node->nid;
$blk_uid = $node->uid;
}
if (!$block['show_citation']) {
unset($node->quotes_citation);
}
unset($node->quotes_bio);
$quote = quotes_view($node, FALSE, FALSE, FALSE, $block['max_length']);
switch ($block['show_titles']) {
case 1:
$quote->content['title'] = array(
'#value' => '<h3>' . drupal_get_path_alias(l($node->title, 'node/' . $nid)) . '</h3>',
'#weight' => -100,
);
break;
case 2:
$quote->content['title'] = array(
'#value' => '<h3>' . check_plain($node->title) . '</h3>',
'#weight' => -100,
);
break;
}
if ($node->comment && !empty($view_text)) {
$quote->content['view_link'] = array(
'#value' => '<div class="quotes-view-link">' . drupal_get_path_alias(l($view_text, 'node/' . $nid)) . '</div>',
'#weight' => $link_weight,
);
}
if ($more_text) {
$quote->content['more_link'] = array(
'#value' => '<div class="quotes-more-link">' . drupal_get_path_alias(l($more_text, 'quotes')) . '</div>',
'#weight' => 2,
);
}
$output .= drupal_render($quote->content);
}
$_quotes_subs = array(
'%' . t('interval') => format_interval($block['cron_interval'] * $block['cron_step'], 1),
'%' . t('bid') => $block['bid'],
'%' . t('title') => $blk_title,
'%' . t('nid') => $blk_nid,
'%' . t('user') => theme('username', user_load(array(
'uid' => $blk_uid,
))),
);
$subject = strtr($block['name'], $_quotes_subs);
return array(
'subject' => $subject,
'content' => $output,
);
case 'configure':
return _quotes_block_configure($delta, $edit);
case 'save':
_quotes_block_configure_save($delta, $edit);
}
}
function _quotes_block_configure($delta = 0, $edit = array()) {
global $_quotes_subs;
drupal_add_js(drupal_get_path('module', 'quotes') . '/quotes.js');
$block = db_fetch_object(db_query("SELECT qb.* FROM {quotes_blocks} qb WHERE bid = %d", $delta));
$any_filters = $block->nid_filter . $block->aid_filter . $block->rid_filter . $block->uid_filter . $block->tid_filter;
$block->aid_filter = explode(',', $block->aid_filter);
$block->rid_filter = explode(',', $block->rid_filter);
$block->uid_filter = explode(',', $block->uid_filter);
$block->tid_filter = explode(',', $block->tid_filter);
$authors = quotes_get_authors();
$roles = user_roles(FALSE, 'create quotes');
foreach (user_roles(FALSE, 'import quotes') as $rid => $role) {
$roles[$rid] = $role;
}
foreach (user_roles(FALSE, 'edit own quotes') as $rid => $role) {
$roles[$rid] = $role;
}
$users = array();
if ($roles[DRUPAL_ANONYMOUS_RID]) {
$users[0] = variable_get('anonymous', t('Anonymous'));
}
$result = db_query("SELECT DISTINCT u.uid, u.name FROM {users} u LEFT JOIN {users_roles} ur ON ur.uid = u.uid WHERE u.uid = 1 OR ur.rid IN (" . implode(',', count($roles) ? array_keys($roles) : array(
0,
)) . ")");
while ($row = db_fetch_object($result)) {
$users[$row->uid] = $row->uid ? $row->name : variable_get('anonymous', t('Anonymous'));
}
$form = array();
if ($delta) {
$form['bid'] = array(
'#type' => 'value',
'#value' => $delta,
);
}
$form['quotes'] = array(
'#type' => 'fieldset',
'#title' => 'Quotes specific settings',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['quotes']['block_type'] = array(
'#type' => 'radios',
'#title' => t('Type'),
'#required' => TRUE,
'#default_value' => $block->block_type == 1 ? 1 : 0,
'#options' => array(
t('Random'),
t('Most recent'),
t('Unpublished'),
),
'#description' => t('"Random" will choose a published quote at random. "Most recent" will display the most recently updated quotes. "Unpublished" will display quotes that are marked as not published (awaiting approval).'),
'#prefix' => '<div class="quotes-radios">',
'#suffix' => '</div>',
);
$sub_str = implode(', ', array_keys($_quotes_subs));
$form['quotes']['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#required' => TRUE,
'#default_value' => $block->name,
'#description' => t("Enter a unique name for this block. This will identify the block on the !block administration page and be used for the default block title. The name may include any of: '%subs'.", array(
'!block administration page' => l(t('block administration page'), 'admin/build/block'),
'%subs' => $sub_str,
)),
);
$title_opts = array(
0 => t('No title'),
1 => t('Title linked to quote'),
2 => t('Plain text'),
);
$form['quotes']['show_titles'] = array(
'#type' => 'radios',
'#options' => $title_opts,
'#title' => t('Show titles'),
'#required' => FALSE,
'#default_value' => $block->show_titles,
'#description' => t('If this option is selected, the titles of the quotes in this block will be shown.'),
'#prefix' => '<div class="quotes-radios">',
'#suffix' => '</div><div class="clear-block"></div>',
);
$form['quotes']['show_citation'] = array(
'#type' => 'checkbox',
'#title' => t('Show citation?'),
'#default_value' => $block->show_citation,
'#description' => t('If this option is selected, the citation for the quote will be included in blocks.'),
);
$form['quotes']['max_length'] = array(
'#type' => 'select',
'#title' => t('Maximum quote length'),
'#options' => drupal_map_assoc(array(
0,
10,
20,
30,
40,
50,
60,
70,
80,
90,
128,
192,
256,
320,
384,
448,
512,
)),
'#default_value' => $block->max_length,
'#description' => t('This will limit the length of a quote shown in the block. A value of zero (0) means no limit.'),
);
$form['quotes']['block_count'] = array(
'#type' => 'select',
'#options' => drupal_map_assoc(array(
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
15,
20,
25,
30,
40,
50,
75,
100,
)),
'#title' => t('Number of quotes in this block'),
'#default_value' => $block->count,
'#description' => t('This sets the maximum number of quotes that will be displayed in this block. Note that "Random" and timed ("Update every") blocks may contain only one quote.'),
);
$form['quotes']['view_text'] = array(
'#type' => 'textfield',
'#title' => t('Block "View" link text'),
'#maxlength' => 64,
'#default_value' => $block->view_text,
'#description' => t('The text of the link to view the quote from a block. Leaving this field blank disables the link.'),
);
$form['quotes']['view_weight'] = array(
'#type' => 'weight',
'#title' => t('"View" link weight'),
'#delta' => 1,
'#default_value' => $block->view_weight,
'#description' => t('A positive value sets the link after the body; a negative value before.'),
);
$form['quotes']['block_more'] = array(
'#type' => 'textfield',
'#title' => t('"More" link text'),
'#maxlength' => 64,
'#default_value' => $block->more_text,
'#description' => t('This sets the text that will display on the "more" link at the bottom of the block. Leave it blank for no link. This is only available for a "Random" block.'),
'#prefix' => '<div class="quotes_block_more">',
);
$frequency = drupal_map_assoc(range(0, 100, 10));
$form['quotes']['rand_freq'] = array(
'#type' => 'select',
'#title' => t('How often block will show'),
'#options' => $frequency,
'#default_value' => isset($block->rand_freq) ? $block->rand_freq : 100,
'#description' => t('This sets the frequency with which the block will be shown. 100% is all the time; 0% is none of the time.'),
'#suffix' => '</div>',
);
$form['quotes']['filters'] = array(
'#type' => 'fieldset',
'#title' => 'Quotes Filters',
'#collapsible' => TRUE,
'#collapsed' => empty($any_filters),
);
$form['quotes']['filters']['nid_filter'] = array(
'#type' => 'textarea',
'#title' => t('Node filter'),
'#rows' => 2,
'#default_value' => $block->nid_filter,
'#description' => t('To restrict this block to display only certain quotes based on node IDs, enter the IDs here separated by commas, spaces, or returns.'),
);
if (count($authors)) {
$form['quotes']['filters']['aid_filter'] = array(
'#type' => 'select',
'#title' => t('Author filter'),
'#multiple' => TRUE,
'#default_value' => $block->aid_filter,
'#options' => $authors,
'#description' => t('To restrict this block to display only quotes from certain authors, select the authors here.'),
);
}
else {
$form['quotes']['filters']['aid_filter'] = array(
'#type' => 'item',
'#title' => t('Author filter'),
'#description' => t('There are no authors. To filter by authors, there must be at least one quote with an attributed author'),
);
}
if (count($roles)) {
$form['quotes']['filters']['rid_filter'] = array(
'#type' => 'select',
'#title' => t('Role filter'),
'#multiple' => TRUE,
'#default_value' => $block->rid_filter,
'#options' => $roles,
'#description' => t('To restrict this block to display only quotes submitted by users in specific roles, select the roles here.'),
);
}
else {
$form['quotes']['filters']['rid_filter'] = array(
'#type' => 'item',
'#title' => t('Role filter'),
'#description' => t('There are no roles configured with the %create quotes, %import quotes, or %edit own quotes permissions, so no roles are available. To filter by role, please assign this permission to at least one role on the !access control page.', array(
'%create quotes' => t('create quotes'),
'%import quotes' => t('import quotes'),
'%edit own quotes' => t('edit own quotes'),
'!access control page' => l(t('access control page'), 'admin/user/access'),
)),
);
}
$form['quotes']['filters']['uid_filter'] = array(
'#type' => 'select',
'#title' => t('User filter'),
'#multiple' => TRUE,
'#default_value' => $block->uid_filter,
'#options' => $users,
'#description' => t('To restrict this block to display only quotes submitted by specific users, select the users here.'),
);
if (function_exists('taxonomy_form_all')) {
$form['quotes']['filters']['tid_filter'] = array(
'#type' => 'select',
'#title' => t('Category filter'),
'#multiple' => TRUE,
'#default_value' => $block->tid_filter,
'#options' => taxonomy_form_all(TRUE),
'#description' => t('To restrict this block to display only quotes in specific categories, select the categories here.'),
);
}
$form['quotes']['cron'] = array(
'#type' => 'fieldset',
'#title' => t('Update options'),
'#description' => t('Note: Timed blocks will contain only one quote.'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['quotes']['cron']['cron_interval'] = array(
'#type' => 'textfield',
'#size' => 4,
'#maxlength' => 3,
'#default_value' => $block->cron_interval ? $block->cron_interval : '',
'#field_prefix' => t('Update every'),
'#prefix' => '<div class="container-inline">',
);
$form['quotes']['cron']['cron_step'] = array(
'#type' => 'select',
'#default_value' => $block->cron_step,
'#options' => array(
60 => t('minutes'),
60 * 60 => t('hours'),
60 * 60 * 24 => t('days'),
60 * 60 * 24 * 7 => t('weeks'),
),
'#suffix' => '</div>',
);
$form['quotes']['cron']['description'] = array(
'#type' => 'item',
'#description' => t('If set, the quote displayed in this block will get updated based on the interval specified (requires cron if page cache is enabled). Leave this value blank to have the quote updated every time the block is viewed.'),
'#prefix' => '<div style="display: block;">',
'#suffix' => '</div>',
);
return $form;
}
function _quotes_block_configure_save($delta, $edit) {
$vals = array(
$edit['name'],
$edit['block_type'],
preg_replace('<[,\\s]+>', ',', trim($edit['nid_filter'])),
implode(',', (array) $edit['aid_filter']),
implode(',', (array) $edit['rid_filter']),
implode(',', (array) $edit['uid_filter']),
implode(',', (array) $edit['tid_filter']),
$edit['cron_interval'] ? $edit['cron_interval'] : 0,
$edit['cron_step'],
$edit['block_type'] == 0 || !empty($edit['cron_interval']) ? 1 : $edit['block_count'],
$edit['show_titles'],
$edit['show_citation'],
$edit['block_type'] == 0 ? $edit['block_more'] : NULL,
$edit['view_text'],
$edit['view_weight'],
$edit['max_length'],
$edit['block_type'] == 0 ? $edit['rand_freq'] : 100,
$delta,
);
db_query("UPDATE {quotes_blocks} SET name = '%s', block_type = %d, nid_filter = '%s', aid_filter = '%s', rid_filter = '%s',\n uid_filter = '%s', tid_filter = '%s', cron_interval = %d, cron_step = %d,\n count = %d, show_titles = %d, show_citation = %d, more_text = '%s',\n view_text = '%s', view_weight = %d, max_length = %d, rand_freq = %d WHERE bid = %d", $vals);
}
function quotes_form_alter($form_id, &$form) {
if ($form_id == 'block_admin_configure' && strpos($_GET['q'], 'admin/build/block/configure/quotes') == 0) {
$form['#validate']['_quotes_block_configuration_validate'] = current($form['#validate']);
}
}
function quotes_cron() {
$result = db_query("SELECT qb.* FROM {quotes_blocks} qb INNER JOIN {blocks} b ON b.module = 'quotes' WHERE b.status = 1 AND qb.cron_interval > 0 AND (qb.vid = 0 OR (qb.cron_last + (qb.cron_step * qb.cron_interval)) < %d)", time());
for ($updated = FALSE; $block = db_fetch_array($result); $updated = TRUE) {
$quotes = quotes_get_quote($block, TRUE, 1);
db_query('UPDATE {quotes_blocks} SET vid = %d, cron_last = %d WHERE bid = %d', $quotes[0], time(), $block['bid']);
}
if ($updated) {
cache_clear_all();
}
}
function quotes_help($path, $args = NULL) {
switch ($path) {
case 'node/add#quotes':
return t('A quote is a famous, infamous, humorous, witty, or otherwise noteworthy quotation or fortune file entry. Quotes can be entered one at a time or mass imported in either tab-separated text or fortune file format.');
case 'node/add/quotes':
return t('Use the form below to enter a single quote.') . (user_access('import quotes') ? ' ' . t('Multiple quotes can also be !mass imported in either tab-separted text or fortune file format.', array(
'!mass imported' => l(t('mass imported'), 'node/add/quotes/import'),
)) : '');
case 'node/add/quotes/import':
$output = t('<p>Use the form below to mass import quotes in either tab-separated text or fortune file format.
Many quotes will be imported in this one step by creating an individual node for each imported quote.
Expand the %Notes section below for more information.</p>', array(
'%Notes' => t('Notes'),
));
$output .= theme('fieldset', array(
'#title' => t('Notes for importing'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#value' => t('<ul>
<li>Tab-separated quotes should appear one quote per line in the format
<em><span style="color: blue;">quote</span><span style="color: red;"><tab></span><span style="color:
green;">author</span></em>. The author and citation are optional; however, the tab is still required.
To import quotes, authors, or citations with more than one line, escape the embedded newlines with a backslash.
Examples:
<pre style="font-size: .75em;">
<span style="color: blue;">Single-line quote.</span><em style="color: red;"><tab></em><span style="color: green;">Author</span>
<span style="color: blue;">Quote without author.</span><em style="color: red;"><tab></em>
<span style="color: blue;">Multi-line quote: line 1...\\
...line 2.</span><em style="color: red;"><tab></em><span style="color: green;">Author line 1\\
Author line 2</span>
<span style="color: blue;">Another quote.<em style="color: red;"><tab></em><span style="color: green;">Another Author</span>
</pre></li>
<li>Fortune files do not explicitly provide an author or attribution
for each quote/fortune. This import will extract an author when
there is a line of the form <em>-- Author</em> with any amount of
leading whitespace. Examples:
<pre style="font-size: .75em;">
<span style="color: blue;">A fortune without an author.</span>
<em style="color: red;">%</em>
<span style="color: blue;">Fortune with author.</span>
--<span style="color: green;">Author</span>
<em style="color: red;">%</em>
<span style="color: blue;">Multi-line fortune: line 1...
...line 2.</span>
-- <span style="color: green;">Author line 1
Author line 2</span>
</pre></li>
<li>Any settings used in the form below (comment, moderation, sticky,
input format, categories, etc.) will be applied to all imported
quotes.</li>
<li>The title entered below will be applied to all quotes. You can use
the variable <em>%id</em> in the title which will be replaced by
the newly-created quote\'s node ID.</li>
<li>Fortune files and tab-separated text data can contain many
quotes. To avoid timeout errors while importing large amounts of
data, consider importing in smaller chunks with no more than 1000
quotes at a time.</li>
<li>If the path module is enabled, you cannot create a path alias
while importing, as the import will attempt to use the same path
for every quote.</li>
</ul>
'),
));
return $output;
case 'admin/settings/quotes':
$text = t('This page displays the status of, and settings for, the quotes module. The permissions for this module are found <a href="!url">here</a>.', array(
'!url' => url('admin/user/access'),
));
$text .= '<p>Version: ' . QUOTES_VERSION . '</p>';
return $text;
case 'admin/settings/quotes/blocks':
return t('You can define any number of blocks that will each display a randomly-selected quote,
the most-recent quotes, or unpublished quotes. The quotes displayed
in each block can be restricted to certain node IDs, roles, users, or
categories. Each block has a name that is used for identification on
on the !block administration page and as the default title when the
block is displayed.', array(
'!block administration page' => l(t('block administration page'), 'admin/build/block'),
));
case 'admin/settings/quotes/add':
return t('Use the form below to define a new quote block.');
case 'admin/help#quotes':
return t('The quotes module allows users to maintain a list of quotations that
they find notable, humorous, famous, infamous, or otherwise worthy of
sharing with website visitors. The quotes can be displayed in any
number of administrator-defined blocks. These blocks will display
quotes based on the restrictions of each block. Blocks can be
configured to restrict to certain nodes, roles, users, or categories.');
case 'user/' . arg(1) . '/quotes':
case 'quotes/author/' . arg(1):
case 'quotes/author':
case 'quotes/' . arg(1):
case 'quotes':
$links = array();
if (user_access('create quotes')) {
$links['add'] = array(
'title' => t('Add another'),
'href' => 'node/add/quotes',
);
}
if (user_access('administer quotes')) {
$links['admin'] = array(
'title' => t('Settings'),
'href' => 'admin/settings/quotes',
'query' => drupal_get_destination(),
);
}
return theme('links', $links);
}
}
function _quotes_trim($text, $length = NULL) {
if (!$length) {
$length = variable_get('weblinks_trim', 0);
}
if ($length == 0) {
return $text;
}
if (drupal_strlen($text) > $length + 3) {
$text = drupal_substr($text, 0, $length) . '...';
}
return $text;
}
function theme_quotes_quote($node, $teaser = FALSE, $bio = TRUE, $max_length = 0) {
global $user;
if ($max_length) {
$text = _quotes_trim($node->body, $max_length);
if (drupal_strlen($text) < drupal_strlen($node->body)) {
$text .= l(t('(more)'), drupal_get_path_alias('node/' . $node->nid));
}
}
else {
$text = $teaser ? $node->teaser : $node->body;
}
$body = check_markup($text, $node->format, $user->uid == $node->uid);
$leader = variable_get('quotes_leader', '—') . ' ';
if (arg(1) == 'author') {
$show_bio = FALSE;
}
else {
$show_bio = variable_get('quotes_author_bio', FALSE);
}
if (variable_get('quotes_author_link', FALSE)) {
$author = $node->quotes_author ? $leader . l($node->quotes_author, 'quotes/author/' . $node->quotes_author, array(
'title' => t('View all quotes by this author'),
)) : '';
$author = decode_entities($author);
}
else {
$author = $node->quotes_author ? check_markup($leader . $node->quotes_author, $node->format, $user->uid == $node->uid) : '';
}
switch ($show_bio) {
case 1:
$bio = $node->quotes_bio ? '<div class="quotes-bio">' . check_markup($node->quotes_bio, $node->format, $user->uid == $node->uid) . '</div>' : '';
break;
case 2:
$bio = $node->quotes_author ? '<div class="quotes-bio-link">' . l(t('See biography and quotes'), 'quotes/author/' . $node->quotes_author, array(
'title' => t('View all quotes by this author'),
)) . '</div>' : '';
break;
default:
$bio = NULL;
}
$citation = $node->quotes_citation ? check_markup("<cite>" . $node->quotes_citation . "</cite>", $node->format, $user->uid == $node->uid) : '';
return '<div class="quotes-quote">' . $body . '</div>' . ($author ? '<div class="quotes-author">' . $author . '</div>' : '') . $bio . ($citation ? '<div class="quotes-citation">' . $citation . '</div>' : '') . '<div class="clear-block"></div>';
}
function theme_quotes_page($uid) {
$limit = variable_get('quotes_per_page', 10);
if (isset($uid)) {
$user = user_load(array(
'uid' => $uid,
'status' => 1,
));
$name = $uid ? module_exists('realname') ? $user->realname : $user->name : variable_get('anonymous', t('Anonymous'));
drupal_set_title(t("!name's quotes", array(
'!name' => $name,
)));
$url = url("quotes/{$uid}/feed");
$result = pager_query(db_rewrite_sql("SELECT n.nid FROM {node} n INNER JOIN {node_revisions} nr USING (vid) WHERE n.status=1 AND n.type='quotes' AND n.uid=%d ORDER BY n.sticky DESC, n.created DESC"), $limit, 0, NULL, $uid);
}
else {
drupal_set_title(t('Quotes'));
$url = url('quotes/feed');
$result = pager_query(db_rewrite_sql("SELECT n.nid, n.sticky FROM {node} n INNER JOIN {node_revisions} nr USING (vid) WHERE n.status = 1 AND n.type = 'quotes' ORDER BY n.sticky DESC, n.created DESC"), $limit);
}
$output = '<div class="quotes">';
while ($node = db_fetch_object($result)) {
$quote = node_load($node->nid);
$output .= node_view($quote, TRUE);
}
$output .= theme('pager', NULL, $limit);
drupal_add_feed($url, t('RSS - !title', array(
'!title' => drupal_get_title(),
)));
return $output . '</div>';
}
function quotes_get_quote($filters = array(), $promoted_only, $limit = 1) {
if ($filters['block_type'] == 0) {
if (isset($filters['rand_freq']) && $filters['rand_freq'] < 100) {
if ($filters['rand_freq'] < rand(0, 100)) {
return array();
}
}
}
$query = 'SELECT n.nid FROM {quotes} q INNER JOIN {node} n ON q.vid=n.vid ' . quotes_block_join_sql($filters) . 'WHERE n.status=' . (int) ($filters['block_type'] != 2) . " AND n.type='quotes' AND " . ($promoted_only ? ' q.promote = 1 AND ' : '') . quotes_block_where_sql($filters) . ' ORDER BY ' . ($filters['block_type'] == 0 ? 'RAND()' : 'n.created DESC');
$result = db_query_range(db_rewrite_sql($query), 0, $limit);
$ret = array();
while ($row = db_fetch_array($result)) {
$ret[] = $row['nid'];
}
return $ret;
}
function quotes_block_join_sql($filters = array(), $aliases = array(
'node' => 'n',
'users_roles' => 'qur',
'users' => 'qu',
'term_node' => 'qtn',
)) {
$join = '';
if ($filters['rid_filter']) {
$join .= " LEFT JOIN {users_roles} {$aliases['users_roles']} ON {$aliases['users_roles']}.uid = {$aliases['node']}.uid ";
}
if ($filters['tid_filter']) {
$join .= " INNER JOIN {term_node} {$aliases['term_node']} ON {$aliases['term_node']}.nid = {$aliases['node']}.nid ";
}
return $join;
}
function quotes_block_where_sql($filters = array(), $aliases = array(
'node' => 'n',
'users_roles' => 'qur',
'users' => 'qu',
'term_node' => 'qtn',
)) {
$where = array();
if ($filters['nid_filter']) {
$where[] = " {$aliases['node']}.nid IN ({$filters['nid_filter']}) ";
}
if ($filters['aid_filter']) {
$where[] = " (q.aid IN ({$filters['aid_filter']})) ";
}
if ($filters['rid_filter']) {
$where[] = sprintf(" ({$aliases['users_roles']}.rid IN ({$filters['rid_filter']}) OR (%d IN ({$filters['rid_filter']}) AND {$aliases['node']}.uid = 0)) ", DRUPAL_ANONYMOUS_RID);
}
if ($filters['uid_filter'] != '') {
$where[] = " {$aliases['node']}.uid IN ({$filters['uid_filter']}) ";
}
if ($filters['tid_filter']) {
$where[] = " {$aliases['term_node']}.tid IN ({$filters['tid_filter']}) ";
}
return $where ? implode(' AND ', $where) : '1=1';
}
function _quotes_page($uid = NULL, $arg2 = NULL) {
global $user;
if ($arg2 == 'feed') {
_quotes_feed_user($uid);
}
else {
return theme('quotes_page', $uid);
}
}
function quotes_author($author = NULL) {
if (!$author) {
return drupal_get_form('quotes_author_form');
}
elseif ($author == t('unspecified')) {
$aid = 0;
$auth = array(
'name' => $author,
'bio' => '',
);
}
else {
if (is_numeric($author)) {
$aid = $author;
$auth = db_fetch_array(db_query("SELECT name, bio FROM {quotes_authors} WHERE aid=%d", $aid));
$author = $auth['name'];
}
else {
$auth = db_fetch_array(db_query("SELECT aid, bio FROM {quotes_authors} WHERE name LIKE('%s%')", $author));
$aid = $auth['aid'];
}
if (!$aid) {
return t("I couldn't locate that author.") . drupal_get_form('quotes_author_form');
}
}
$limit = variable_get('quotes_per_page', 10);
drupal_set_title(decode_entities(t('Quotes by @name', array(
'@name' => $author,
))));
if ($auth['bio']) {
$output = '<div class="quotes-header-bio clear-block">' . check_markup($auth['bio']) . '</div>';
}
$result = pager_query(db_rewrite_sql("SELECT n.nid FROM {node} n INNER JOIN {node_revisions} nr USING (vid) INNER JOIN {quotes} q USING (vid) WHERE q.aid='%d' AND n.status=1 AND n.type='quotes' ORDER BY n.sticky DESC, n.created DESC"), $limit, 0, NULL, $aid);
$output .= '<div class="quotes">';
while ($node = db_fetch_object($result)) {
$output .= node_view(node_load($node->nid), FALSE);
}
$output .= theme('pager', NULL, $limit);
return $output . '</div>';
}
function quotes_author_form() {
$form = array();
$max_name_length = 78;
$authors = quotes_get_authors();
$author_names = array();
foreach ($authors as $aid => $name) {
$name = filter_xss($name, array());
if (drupal_strlen($name) > $max_name_length) {
$name = drupal_substr($name, 0, $max_name_length - 3) . '...';
}
$author_names[$aid] = $name;
}
$form['author'] = array(
'#type' => 'select',
'#options' => $author_names,
'#size' => min(25, count($authors)),
'#description' => t('Select an author from the list.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Select'),
);
return $form;
}
function quotes_author_form_submit($form_id, $form_values) {
drupal_goto('quotes/author/' . $form_values['author']);
}
function _quotes_feed_user($uid) {
global $user;
$luser = $uid ? user_load(array(
'uid' => $uid,
'status' => 1,
)) : $user;
$result = db_query_range(db_rewrite_sql("SELECT n.nid, nr.title, nr.teaser, n.created, u.name, u.uid FROM {node} n INNER JOIN {node_revisions} nr ON nr.vid = n.vid INNER JOIN {users} u ON u.uid = n.uid WHERE n.status = 1 AND n.type = 'quotes' AND u.uid = %d ORDER BY n.created DESC"), $luser->uid, 0, 15);
node_feed($result, array(
'title' => t("!name's quotes", array(
'!name' => $luser->uid ? $luser->name : variable_get('anonymous', t('Anonymous')),
)),
'link' => url("quotes/{$luser->uid}", NULL, NULL, TRUE),
));
}
function _quotes_feed_last() {
$result = db_query_range(db_rewrite_sql("SELECT n.nid, nr.title, nr.teaser, n.created, u.name, u.uid FROM {node} n INNER JOIN {node_revisions} nr ON nr.vid = n.vid INNER JOIN {users} u ON u.uid = n.uid WHERE n.status = 1 AND n.type = 'quotes' ORDER BY n.created DESC"), 0, 15);
node_feed($result, array(
'title' => variable_get('site_name', 'drupal') . ' ' . t('quotes'),
'link' => url("quotes", NULL, NULL, TRUE),
));
}
function _quotes_parse_import($node, $set_errors = FALSE) {
$quotes = array();
if ($node->quotes_format == 'text') {
$node->body = str_replace('<tab>', "\t", $node->body);
foreach (explode("\r", str_replace("\\\r", "\n", preg_replace('<(?:\\r\\n?|\\n)>', "\r", trim($node->body)))) as $quote) {
$quote = explode("\t", $quote);
if (count($quote) < 2 || !trim($quote[0])) {
if ($set_errors) {
form_set_error('body', t('Parse error on quote !num.', array(
'!num' => count($quotes) + 1,
)));
}
break;
}
$new_quote = drupal_clone($node);
$new_quote->body = trim($quote[0]);
$new_quote->quotes_author = $quote[1];
$new_quote->quotes_citation = $quote[2];
$quotes[] = $new_quote;
}
}
elseif ($node->quotes_format == 'fortune') {
foreach (preg_split('<\\n+%+\\n+>', str_replace("\t", ' ', preg_replace('<(?:\\r\\n?|\\n)>', "\n", $node->body))) as $quote) {
if (preg_match('<^(?:(?:(.*)\\n+\\s*--\\s*(.*?)))$>s', $quote, $matches)) {
if (!trim($matches[1])) {
if ($set_errors) {
form_set_error('body', t('Parse error on quote !num.', array(
'!num' => count($quotes) + 1,
)));
}
break;
}
$quotes[] = (object) array(
'body' => trim($matches[1]),
'quotes_author' => $matches[2],
'quotes_citation' => NULL,
'format' => $node->format,
);
}
else {
if (!trim($quote)) {
if ($set_errors) {
form_set_error('body', t('Parse error on quote !num.', array(
'!num' => count($quotes) + 1,
)));
}
break;
}
$quotes[] = (object) array(
'body' => trim($quote),
'format' => $node->format,
);
}
}
}
elseif ($set_errors) {
form_set_error('quotes_format', t('Please select a valid import format.'));
}
return $quotes;
}
function _quotes_admin_settings() {
$form = array();
$count = db_result(db_query("SELECT COUNT(*) FROM {node} n where n.type='quotes' AND n.status=1"));
$form['count'] = array(
'#type' => 'item',
'#value' => t('There are currently !count published quotations.', array(
'!count' => $count,
)),
);
$form['display'] = array(
'#type' => 'fieldset',
'#title' => t('Display Options'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#description' => t('These options are for general theming.'),
);
$form['display']['quotes_leader'] = array(
'#type' => 'textfield',
'#title' => t('Author leader'),
'#default_value' => variable_get('quotes_leader', '—'),
'#description' => t('The text placed before the author attribution (e.g. "&mdash;" for an em-dash or "&#8226;" for a bullet).'),
);
$form['display']['quotes_author_link'] = array(
'#type' => 'checkbox',
'#title' => t('Make author a link'),
'#default_value' => variable_get('quotes_author_link', FALSE),
'#description' => t('If selected, the author text will be a link to show all quotes by that author.'),
);
$form['display']['quotes_author_bio'] = array(
'#type' => 'radios',
'#options' => array(
0 => t("Don't display"),
1 => t('Include text'),
2 => t('Include as a link'),
),
'#title' => t("Include author's bio"),
'#default_value' => variable_get('quotes_author_bio', FALSE),
'#description' => t("If selected, the author's biography will be shown on the Quotes page."),
);
$form['display']['quotes_per_page'] = array(
'#type' => 'textfield',
'#title' => t('Quotes per page'),
'#size' => 6,
'#default_value' => variable_get('quotes_per_page', 10),
'#description' => t('The number of quotes included on a page.'),
);
$form['display']['quotes_edit_link'] = array(
'#type' => 'checkbox',
'#title' => t('Add an "edit" link'),
'#default_value' => variable_get('quotes_edit_link', TRUE),
'#description' => t('If selected, an "edit" link will be shown for each quote.'),
);
$form['myquotes'] = array(
'#type' => 'fieldset',
'#title' => t('My Quotes links'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['myquotes']['quotes_showlink'] = array(
'#type' => 'checkbox',
'#title' => t('Show link to users\' quotes'),
'#default_value' => variable_get('quotes_showlink', TRUE),
'#description' => t('Uncheck this to disable the link to each users\' "my quotes" page when viewing a node.'),
);
$form['myquotes']['quotes_show_myquotes'] = array(
'#type' => 'checkbox',
'#title' => t('Show the "my quotes" menu item'),
'#default_value' => variable_get('quotes_show_myquotes', 1),
'#description' => t('Uncheck this to disable the "my quotes" menu item for all users.'),
);
$form['user'] = array(
'#type' => 'fieldset',
'#title' => t('User Options'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#description' => t('These options are for users.'),
);
$form['user']['quotes_user_recent'] = array(
'#type' => 'checkbox',
'#title' => t('Add a "Recent quotes" link on the "My account" page?'),
'#default_value' => variable_get('quotes_user_recent', flase),
);
return system_settings_form($form);
}
function quotes_export() {
$form['intro'] = array(
'#type' => 'item',
'#title' => t('Copy and paste this list to the receiving site.'),
);
$output = NULL;
$count = 0;
$sql = db_rewrite_sql("SELECT nr.body, nr.title, qa.name AS author, q.citation FROM {node} n INNER JOIN {node_revisions} nr USING (vid) INNER JOIN {quotes} q USING (vid) INNER JOIN {quotes_authors} qa USING (aid) WHERE n.status=1 AND n.type='quotes' ORDER BY qa.name");
$result = db_query($sql);
while ($row = db_fetch_object($result)) {
++$count;
$output .= _quotes_escape_newlines($row->body) . "\t" . _quotes_escape_newlines($row->author) . "\t" . _quotes_escape_newlines($row->citation) . "\n";
}
drupal_set_message(t('Found !count quotes.', array(
'!count' => $count,
)));
if ($count == 0) {
$count = 1;
$output = t('No quotes were found.');
}
$form['list'] = array(
'#type' => 'textarea',
'#value' => $output,
'#rows' => min(30, $count),
);
return $form;
}
function quotes_bios($aid = NULL) {
$form = array();
$first_pass = is_null($aid);
if ($first_pass) {
$auths = quotes_get_authors();
$count = count($auths);
$data = array(
'name' => NULL,
'bio' => NULL,
);
}
else {
$data = db_fetch_array(db_query("SELECT * FROM {quotes_authors} WHERE aid=%d", $aid));
}
$form['aid'] = array(
'#type' => 'hidden',
'#value' => $aid,
);
$form['author'] = array(
'#type' => 'select',
'#options' => $auths,
'#size' => min(20, $count),
'#description' => t('Pick the author whose biography you wish to update.'),
);
$form['name'] = array(
'#type' => 'markup',
'#value' => '<h3>' . t('Biography for %name', array(
'%name' => $data['name'],
)) . '</h3>',
);
$form['bio'] = array(
'#type' => 'textarea',
'#description' => t("This is the author's biography."),
'#default_value' => $data['bio'],
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => $first_pass ? t('Get biography') : t('Update'),
);
if ($first_pass) {
$form['name']['#type'] = 'hidden';
$form['bio']['#type'] = 'hidden';
}
else {
$form['author']['#type'] = 'hidden';
}
return $form;
}
function quotes_bios_submit($form_id, $form_values) {
if ($form_values['op'] == 'Update') {
$vals = array(
$form_values['bio'],
$form_values['aid'],
);
$upd = db_query("UPDATE {quotes_authors} SET bio='%s' WHERE aid=%d", $vals);
return BIOS_PATH;
}
else {
return BIOS_PATH . '/' . $form_values['author'];
}
}
function _quotes_escape_newlines($text) {
$text = str_replace("\r", '', $text);
return str_replace("\n", "\\\n", $text);
}
function _quotes_block_configuration_validate($form_id, $form_values) {
if (trim($form_values['nid_filter']) && !preg_match('<^(\\d+[,\\s]*)+$>', trim($form_values['nid_filter']))) {
form_set_error('nid_filter', t('Please enter valid node IDs.'));
}
$interval = $form_values['cron_interval'];
if ($interval != '' && (!preg_match('<^\\d+$>', $interval) || $interval < 1 || $interval > 999)) {
form_set_error('cron_interval', t('The update interval must be between 1 and 999.'));
}
}
function _quotes_blocks() {
$form = array();
$form['name'] = array(
'#type' => 'textfield',
'#size' => 32,
'#maxlength' => 64,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Add block'),
);
return $form;
}
function _quotes_blocks_validate($form_id, $form_values) {
$name = trim($form_values['name']);
if (!$name) {
form_set_error('name', t('You must specify a valid block name.'));
}
else {
if (db_result(db_query("SELECT COUNT(*) FROM {quotes_blocks} qb WHERE qb.name = '%s'", $name))) {
form_set_error('name', t('The block name %name already exists. Please choose another block name.', array(
'%name' => $name,
)));
}
}
}
function _quotes_blocks_submit($form_id, $form_values) {
db_query("INSERT INTO {quotes_blocks} (bid, name, block_type, nid_filter, aid_filter, rid_filter, uid_filter, tid_filter, cron_interval, cron_step, cron_last, vid) VALUES (%d, '%s', 0, '', '', '', '', '', 0, 0, 0, 0)", db_next_id('{quotes_blocks}_bid'), trim($form_values['name']));
}
function theme__quotes_blocks($form) {
$header = array(
t('Name'),
t('Filters'),
array(
'data' => t('Operations'),
'colspan' => 2,
),
);
$result = db_query('SELECT qb.* FROM {quotes_blocks} qb ORDER BY qb.name');
$rows = array();
while ($block = db_fetch_object($result)) {
$filters = array();
if ($block->nid_filter) {
$filters[] = t('node');
}
if ($block->rid_filter) {
$filters[] = t('role');
}
if ($block->uid_filter) {
$filters[] = t('user');
}
if ($block->tid_filter) {
$filters[] = t('term');
}
$rows[] = array(
$block->name,
implode(', ', count($filters) ? $filters : array(
t('none'),
)),
l(t('configure block'), "admin/build/block/configure/quotes/{$block->bid}"),
l(t('delete block'), "admin/settings/quotes/delete/{$block->bid}"),
);
}
$rows[] = array(
drupal_render($form['name']),
array(
'data' => drupal_render($form['submit']),
'colspan' => 3,
),
);
$output = drupal_render($form);
if (count($rows)) {
$output .= theme('table', $header, $rows);
}
else {
$output .= theme('table', $header, array(
array(
array(
'data' => t('No blocks are defined.'),
'colspan' => 4,
),
),
));
}
return $output;
}
function _quotes_block_delete($bid) {
$block = db_fetch_object(db_query('SELECT qb.name FROM {quotes_blocks} qb WHERE qb.bid = %d', $bid));
$form = array();
$form['bid'] = array(
'#type' => 'value',
'#value' => $bid,
);
$form['block_name'] = array(
'#type' => 'value',
'#value' => $block->name,
);
return confirm_form($form, t('Are you sure you want to delete the block %name?', array(
'%name' => $block->name,
)), 'admin/settings/quotes/blocks', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
}
function _quotes_block_delete_submit($form_id, $form_values) {
db_query("DELETE FROM {quotes_blocks} WHERE bid = %d", $form_values['bid']);
drupal_set_message(t('The block %name has been removed.', array(
'%name' => $form_values['block_name'],
)));
cache_clear_all();
return 'admin/settings/quotes/blocks';
}
function quotes_get_authors() {
$list = array();
$unknown = -1;
$result = db_query('SELECT qa.aid, qa.name, COUNT(q.nid) as count FROM {quotes_authors} qa LEFT JOIN {quotes} q USING(aid) GROUP BY qa.name ORDER BY qa.name');
while ($row = db_fetch_array($result)) {
if (empty($row['name'])) {
$unknown = $row['aid'];
}
if ($row['count']) {
$list[$row['aid']] = $row['name'];
}
else {
db_query("DELETE FROM {quotes_authors} WHERE aid=%d", $row['aid']);
watchdog('Quotes', t('Deleted aid=!aid (!name) because of no quotes.', array(
'!aid' => $row['aid'],
'!name' => drupal_substr(filter_xss($row['name'], array()), 0, 40),
)));
}
}
if ($unknown != -1) {
$list[$unknown] = t('unspecified');
}
return $list;
}
function quotes_get_citations() {
$list = array();
$result = db_query('SELECT DISTINCT(citation) FROM {quotes} ORDER BY citation');
while ($row = db_fetch_array($result)) {
$list[$row['citation']] = $row['citation'];
}
$list[' '] = t('unspecified');
return $list;
}
function quotes_token_values($type, $object = NULL) {
$values = array();
switch ($type) {
case 'all':
case 'node':
$author = empty($object->quotes_author) ? 'unspecified' : $object->quotes_author;
$values['quotes-author'] = decode_entities(check_plain($author));
$values['quotes-author-raw'] = $author;
$values['quotes-author-id'] = $object->quotes_aid;
break;
}
return $values;
}
function quotes_token_list($type = 'all') {
$tokens = array();
switch ($type) {
case 'all':
case 'node':
$tokens['node']['quotes-author'] = t('The author of this quote.');
$tokens['node']['quotes-author-raw'] = t('The author of this quote. WARNING - raw user input.)');
$tokens['node']['quotes-author-id'] = t('The author id of this quote.)');
break;
}
return $tokens;
}