/[drupal]/contributions/modules/teaser_block/teaser_block.module
ViewVC logotype

Contents of /contributions/modules/teaser_block/teaser_block.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.9 - (show annotations) (download) (as text)
Fri Oct 3 00:17:02 2008 UTC (13 months, 3 weeks ago) by sun
Branch: MAIN
CVS Tags: HEAD
Changes since 1.8: +2 -2 lines
File MIME type: text/x-php
by sun: Fixed read more link placed before last character of teaser text.
1 <?php
2 // $Id: teaser_block.module,v 1.8 2008/10/03 00:04:36 sun Exp $
3
4 /**
5 * @file
6 * Implements teaser blocks for nodes.
7 */
8
9 /**
10 * Implementation of hook_perm().
11 */
12 function teaser_block_perm() {
13 return array('create teaser blocks');
14 }
15
16 /**
17 * Implementation of hook_menu().
18 */
19 function teaser_block_menu() {
20 $items = array();
21 $items['admin/build/block/add-teaser'] = array(
22 'title' => 'Add teaser block',
23 'page callback' => 'drupal_get_form',
24 'page arguments' => array('teaser_block_form'),
25 'access arguments' => array('create teaser blocks'),
26 'type' => MENU_LOCAL_TASK,
27 );
28 return $items;
29 }
30
31 /**
32 * Implementation of hook_theme().
33 */
34 function teaser_block_theme() {
35 return array(
36 'teaser_block_read_more_link' => array(
37 'arguments' => array('data' => NULL),
38 )
39 );
40 }
41
42 /**
43 * Implementation of hook_block().
44 */
45 function teaser_block_block($op = 'list', $delta = 0, $edit = array()) {
46 switch ($op) {
47 case 'list':
48 return teaser_block_list();
49
50 case 'view':
51 return teaser_block_view($delta);
52
53 case 'configure':
54 return teaser_block_form(NULL, $delta);
55
56 case 'save':
57 $form_state = array('values' => $edit);
58 teaser_block_form_submit(NULL, $form_state);
59 break;
60 }
61 }
62
63 /**
64 * Return a list of teaser blocks for block overview page.
65 */
66 function teaser_block_list() {
67 $blocks = array();
68 $result = db_query("SELECT tb.bid, tb.info FROM {teaser_block} tb ORDER BY tb.info");
69 while ($block = db_fetch_object($result)) {
70 $blocks[$block->bid]['info'] = $block->info;
71 }
72 return $blocks;
73 }
74
75 /**
76 * Return the block requested by $bid.
77 */
78 function teaser_block_view($bid) {
79 $sql = 'SELECT t.nid, t.title, t.body, t.format FROM {teaser_block} t INNER JOIN {node} n ON n.nid = t.nid WHERE t.bid = %d AND n.status = 1';
80 if ($data = db_fetch_object(db_query($sql, $bid))) {
81 // Translatable support.
82 if (function_exists('tobject')) {
83 $data = tobject('block', 'teaser_block-'. $bid .'-'. $GLOBALS['theme'], $data);
84 }
85 $block['subject'] = check_plain($data->title);
86 $block['content'] = theme('teaser_block_read_more_link', $data);
87 return $block;
88 }
89 }
90
91 /**
92 * Return block content including a link to the node.
93 *
94 * @ingroup themeable
95 */
96 function theme_teaser_block_read_more_link($data) {
97 $content = trim(check_markup($data->body, $data->format, FALSE));
98 $link = '<span class="teaser_block-more-link">';
99 $link .= l(t('Read more'), 'node/'. $data->nid, array('attributes' => array('title' => t('Read the rest of this posting.')), 'html' => TRUE));
100 $link .= '</span>';
101
102 // Insert read more link before an image at the end of block content.
103 $stripped = trim(strip_tags($content));
104 $last_chars = substr($stripped, -60);
105 if (strpos($content, $last_chars) !== FALSE) {
106 $content = preg_replace('/('. preg_quote($last_chars) .')/', '$1'. $link, $content);
107 }
108 // Insert read more link before closing tag.
109 else if (substr($content, -1) == '>') {
110 $content = preg_replace('@(</.+>)$@', $link .'$1', $content);
111 }
112 // Insert read more link at the end.
113 else {
114 $content .= $link;
115 }
116
117 return $content;
118 }
119
120 /**
121 * Implementation of hook_form_alter().
122 *
123 * Allows to enable/disable teaser blocks for content-types.
124 */
125 function teaser_block_form_alter(&$form, &$form_state, $form_id) {
126 if ($form_id == 'node_type_form' && isset($form['identity']['type'])) {
127 $types = variable_get('teaser_block_types', array());
128 $form['workflow']['teaser_block'] = array(
129 '#type' => 'radios',
130 '#title' => t('Teaser blocks'),
131 '#default_value' => (int)isset($types[$form['#node_type']->type]),
132 '#options' => array(t('Disabled'), t('Enabled')),
133 '#description' => t('Enables teaser blocks for this content-type.'),
134 );
135 array_unshift($form['#submit'], 'teaser_block_node_type_submit');
136 }
137 }
138
139 /**
140 * Submit handler for node type form.
141 */
142 function teaser_block_node_type_submit($form, &$form_state) {
143 $types = variable_get('teaser_block_types', array());
144 if ($form_state['values']['teaser_block']) {
145 $types = array_merge($types, array($form_state['values']['type'] => $form_state['values']['teaser_block']));
146 }
147 else {
148 unset($types[$form_state['values']['type']]);
149 }
150 variable_set('teaser_block_types', $types);
151 unset($form_state['values']['teaser_block']);
152 }
153
154 function teaser_block_form($form_state, $delta = 0) {
155 $teaser_block = db_fetch_array(db_query('SELECT bid, nid, title, body, format FROM {teaser_block} WHERE bid = %d', $delta));
156
157 $form['delta'] = array(
158 '#type' => 'value',
159 '#value' => $delta,
160 );
161
162 $form['title'] = array(
163 '#type' => 'textfield',
164 '#title' => t('Block title'),
165 '#default_value' => $teaser_block['title'],
166 '#description' => t('Enter a title to display for this block or <em>&lt;none&gt;</em> to display no title. Leave empty to use the title of the referenced content.')
167 );
168
169 $options = array('' => t('- Please select -'));
170 $types = variable_get('teaser_block_types', array());
171 $types = (!empty($types) ? "WHERE n.type IN ('". implode("','", array_keys($types)) ."')" : '');
172 $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n '. $types .' ORDER BY n.title'));
173 while ($node = db_fetch_object($result)) {
174 $options[$node->nid] = $node->title;
175 }
176 $form['nid'] = array(
177 '#type' => 'select',
178 '#title' => t('Link <em>read more</em> to'),
179 '#default_value' => $teaser_block['nid'],
180 '#required' => TRUE,
181 '#options' => $options,
182 );
183
184 $form['body'] = array(
185 '#type' => 'textarea',
186 '#title' => t('Teaser text'),
187 '#default_value' => $teaser_block['body'],
188 '#cols' => 60,
189 '#rows' => 10,
190 '#description' => t('Enter a teaser text to display within the block. It will be displayed along with a <em>read more</em> link which links to this content. Leave empty to automatically extract the teaser from this content.')
191 );
192 $form['format'] = filter_form(!empty($teaser_block['format']) ? $teaser_block['format'] : FILTER_FORMAT_DEFAULT, NULL, array('format'));
193
194 $form['submit'] = array(
195 '#type' => 'submit',
196 '#value' => t('Save'),
197 );
198 if ($delta) {
199 $form['delete'] = array(
200 '#type' => 'submit',
201 '#value' => t('Delete'),
202 );
203 }
204
205 return $form;
206 }
207
208 function teaser_block_form_submit($form, &$form_state) {
209 if ($form_state['values']['op'] == t('Save')) {
210 // Insert node title if teaser block title was left empty.
211 if (trim($form_state['values']['title']) == '') {
212 $node = node_load($form_state['values']['nid']);
213 $form_state['values']['title'] = $node->title;
214 }
215 // Insert node teaser if teaser block body was left empty.
216 if (trim($form_state['values']['body']) == '') {
217 $node = node_load($form_state['values']['nid']);
218 $form_state['values']['body'] = node_teaser($node->body);
219 }
220 }
221
222 // Update teaser block in the database.
223 $block = new stdClass;
224 $block->delta = $form_state['values']['delta'];
225 $block->title = $form_state['values']['title'];
226 $block->nid = $form_state['values']['nid'];
227 $block->body = $form_state['values']['body'];
228 $block->format = $form_state['values']['format'];
229 if ($form_state['values']['op'] == t('Save')) {
230 teaser_block_update($block->delta ? 'update' : 'insert', $block);
231 }
232 else if ($form_state['values']['op'] == t('Delete')) {
233 teaser_block_update('delete', $block);
234 }
235
236 $form_state['redirect'] = 'admin/build/block';
237 }
238
239 /**
240 * Implementation of hook_nodeapi.
241 */
242 function teaser_block_nodeapi(&$node, $op, $arg) {
243 switch ($op) {
244 case 'update':
245 teaser_block_update('update status', $node);
246 return;
247
248 case 'delete':
249 // Does not work with #translatable. 09/04/2008 sun
250 // teaser_block_update('delete', $node);
251 return;
252 }
253 }
254
255 /**
256 * Insert/update a block in the database.
257 */
258 function teaser_block_update($op, $block) {
259 global $theme_key;
260 switch ($op) {
261 case 'update':
262 $sql = "UPDATE {teaser_block} SET nid = %d, title = '%s', body = '%s', info = '%s', format = %d WHERE bid = %d";
263 db_query($sql, $block->nid, $block->title, $block->body, _teaser_block_info($block->title, $block->delta), $block->format, $block->delta);
264
265 drupal_set_message(t('Teaser block %title was updated.', array('%title' => $block->title)));
266 return;
267
268 case 'update status':
269 // Note: $block is a node here.
270 $result = db_query("SELECT tb.bid FROM {teaser_block} tb WHERE tb.nid = %d", $block->nid);
271 $bids = array();
272 while ($item = db_fetch_array($result)) {
273 $bids[] = $item['bid'];
274 }
275 if (!empty($bids)) {
276 db_query("UPDATE {blocks} SET status = %d WHERE module = 'teaser_block' AND delta IN (%s)", $block->status, implode(',', $bids));
277 drupal_set_message(t('Publishing status of teaser block(s) for %title has been updated.', array('%title' => $block->title)));
278 }
279 return;
280
281 case 'insert':
282 $sql = "INSERT INTO {teaser_block} (nid, title, body, info, format) VALUES (%d, '%s', '%s', '%s', %d)";
283 db_query($sql, $block->nid, $block->title, $block->body, _teaser_block_info($block->title, 0), $block->format);
284
285 $block->delta = db_last_insert_id('teaser_block', 'bid');
286 $sql = "INSERT INTO {blocks} (module, delta, theme) VALUES ('%s', %d, '%s')";
287 db_query($sql, 'teaser_block', $block->delta, $theme_key);
288
289 drupal_set_message(t('Teaser block %title was created.', array('%title' => $block->title)));
290 return;
291
292 case 'delete':
293 $bids = array();
294 if (!isset($block->delta)) {
295 // Note: $block is a node here.
296 $result = db_query("SELECT tb.bid FROM {teaser_block} tb WHERE tb.nid = %d", $block->nid);
297 while ($item = db_fetch_array($result)) {
298 $bids[] = $item['bid'];
299 }
300 }
301 else {
302 $bids = array($block->delta);
303 }
304 if (!empty($bids)) {
305 db_query("DELETE FROM {blocks} WHERE module = 'teaser_block' AND delta IN (%s)", implode(',', $bids));
306 db_query("DELETE FROM {teaser_block} WHERE bid IN (%s)", implode(',', $bids));
307 drupal_set_message(t('Teaser block(s) for %title have been deleted.', array('%title' => $block->title)));
308 }
309 return;
310 }
311 }
312
313 /**
314 * Return a unique teaser block description.
315 */
316 function _teaser_block_info($title, $bid = 0) {
317 $x = 0;
318 $info = t('Teaser: @title', array('@title' => $title));
319 // Append block counter.
320 while (db_result(db_query("SELECT info FROM {boxes} WHERE bid != %d AND info = '%s'", $bid, $info))) {
321 $info = ($x == 0 ? $info : substr($info, 0, strrpos($info, '#') - 1)) .' #'. ++$x;
322 }
323 return $info;
324 }
325
326 /**
327 * Implementation of hook_panels_include_directory().
328 */
329 function teaser_block_panels_include_directory($plugintype) {
330 switch ($plugintype) {
331 case 'content_types':
332 return $plugintype;
333 }
334 }
335

  ViewVC Help
Powered by ViewVC 1.1.2