/[drupal]/contributions/modules/node_template/nodetemplate.module
ViewVC logotype

Contents of /contributions/modules/node_template/nodetemplate.module

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


Revision 1.5 - (show annotations) (download) (as text)
Tue Jun 26 08:35:21 2007 UTC (2 years, 5 months ago) by motou
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +40 -4 lines
File MIME type: text/x-php
add the feature to let the user decide if a duplication is needed while setting a node as template.
1 <?php
2
3 // $Id: nodetemplate.module,v 1.3.2.3 2007/06/26 08:20:18 motou Exp $
4
5 /**
6 * Implementation of hook_help().
7 */
8 function nodetemplate_help($section) {
9 switch ($section) {
10 case 'admin/help#nodetemplate':
11 $output = '<p>'. t('The node template module allows users to make any existing node and use it as a template. The authorship is set to the current user, the menu and url aliases are reset, and the words "Clone of" are inserted into the title to remind you that you are not editing the original node.') .'</p>';
12 $output .= '<p>'. t('Users with the "node template" permission can utilize this functionality. A tab named "set template" will appear on every editable pages. Once you click this tab you have <em>already</em> created a new node that is a copy of the node you were viewing, and you will be redirected to an edit screen for that new node.') .'</p>';
13 return $output;
14 case 'admin/modules#description':
15 return t('Allows users to duplicate an existing node and set it as a template.');
16 }
17 }
18
19 /**
20 * Implementation of hook_perm().
21 */
22 function nodetemplate_perm() {
23 return array('access node template');
24 }
25
26 /**
27 * Implementation of hook_menu().
28 */
29 function nodetemplate_menu($may_cache) {
30 $items = array();
31
32 if (!$may_cache) {
33 if (arg(0) == 'node' && is_numeric(arg(1))){
34 $node=node_load(arg(1));
35 if ($node->nid) {
36 $access = (user_access('access node template') && filter_access($node->format) && node_access('create',$node->type));
37 $items[] = array('path' => 'node/'. $node->nid.'/template',
38 'title' => t('set template'),
39 'callback' => 'nodetemplate_confirm',
40 'access' => $access,
41 'type' => MENU_LOCAL_TASK,
42 'weight' => 5);
43 }
44 }
45 }
46
47 if ($may_cache) {
48 $access = user_access('access node template');
49
50 $items[] = array(
51 'path' => 'nodetemplate',
52 'title' => t('my node templates'),
53 'callback' => 'nodetemplate_admin',
54 'access' => $access);
55
56 $items[] = array(
57 'path' => 'nodetemplate/list',
58 'title' => t('list'),
59 'type' => MENU_DEFAULT_LOCAL_TASK,
60 'weight' => -10);
61
62 $items[] = array(
63 'path' => 'nodetemplate/configure',
64 'title' => t('configure'),
65 'callback' => 'nodetemplate_configure',
66 'access' => user_access('access node template'),
67 'type' => MENU_LOCAL_TASK);
68
69 $items[] = array(
70 'path' => 'nodetemplate/delete',
71 'title' => t('delete'),
72 'callback' => 'nodetemplate_delete',
73 'type' => MENU_CALLBACK);
74
75 }
76 return $items;
77 }
78
79 /**
80 * Implementation of hook_settings().
81 */
82 function nodetemplate_settings() {
83
84 $form['heading'] = array(
85 '#value' => '<b>'.t('Configuration options for the node template module:').'</b>',
86 );
87
88 $form['node_template_without_confirm'] = array(
89 '#type' => 'checkbox',
90 '#title' => t('Set template needs no confirmation'),
91 '#default_value' => variable_get('node_template_without_confirm', FALSE),
92 '#description' => t('If this is set, a new node will be created immediately after clicking the "set template" tab when viewing a node.'),
93 );
94
95 $form['node_template_without_clone'] = array(
96 '#type' => 'checkbox',
97 '#title' => t('Set template but without duplicating the node'),
98 '#default_value' => variable_get('node_template_without_clone', TRUE),
99 '#description' => t('If this is set, a new node will be created immediately after clicking the "set template" tab when viewing a node.'),
100 );
101
102 $form['node_template_with_child'] = array(
103 '#type' => 'checkbox',
104 '#title' => t('Book pages should be duplicated with all the children'),
105 '#default_value' => variable_get('node_template_with_child', FALSE),
106 '#description' => t('If this is set, a new book page with all the children will be created after clicking the "set template" tab when viewing a node.'),
107 );
108
109 $form['publishing'] = array(
110 '#type' => 'fieldset',
111 '#title' => '<b>'.t('Should the publishing options ( e.g. published, promoted, etc) be reset to the defaults?').'</b>',
112 );
113
114 foreach (node_get_types() as $type => $name) {
115 $form['publishing']['clone_reset_'. $type] = array(
116 '#type' => 'checkbox',
117 '#title' => t('%s: reset publishing options when cloned', array('%s' => $name)),
118 '#default_value' => variable_get('clone_reset_'. $type, FALSE),
119 );
120 }
121
122 return $form;
123 }
124
125 /**
126 * Menu callback: prompt the user to confirm the operation
127 */
128 function nodetemplate_confirm() {
129
130 if (variable_get('node_template_without_confirm', FALSE)) {
131 if (variable_get('node_template_without_clone', TRUE)) {
132 $nid = $form_values['nid'];
133 $existed_node = db_num_rows(db_query('SELECT * FROM {node_template} WHERE nid = %d', $nid));
134 if ($existed_node > 0) {
135 db_query('UPDATE {node_template} SET is_template = 1 WHERE nid = %d', $nid);
136 }
137 else {
138 db_query("INSERT INTO {node_template} (nid, is_template) VALUES (%d, %d)", $nid, 1);
139 }
140 drupal_goto('node/'.$nid);
141 }
142 else {
143 duplicate_node($form_values['nid']);
144 }
145 }
146 else {
147 $node = node_load(arg(1));
148 $description = (variable_get('node_template_without_clone', TRUE))?
149 t('This action will set the current node as template without duplicating it now, and then you can duplicate the node later.'):
150 t('This action will create a new node or a set of book pages, and then you will be redirected to editing the new node.');
151 $form['nid'] = array('#type' => 'value', '#value' => $node->nid);
152 $output = confirm_form('nodetemplate_confirm', $form,
153 t('Do you really want to set %title as a template?', array('%title' => theme('placeholder', $node->title))),
154 'node/'. $node->nid,'<p>'.$description. '</p>',
155 t('Next'), t('Cancel'));
156
157 return $output;
158 }
159 }
160
161 /**
162 * Handle confirm form submission
163 */
164 function nodetemplate_confirm_submit($form_id, $form_values) {
165 if ($form_values['confirm']) {
166 if (variable_get('node_template_without_clone', TRUE)) {
167 $nid = $form_values['nid'];
168 $existed_node = db_num_rows(db_query('SELECT * FROM {node_template} WHERE nid = %d', $nid));
169 if ($existed_node > 0) {
170 db_query('UPDATE {node_template} SET is_template = 1 WHERE nid = %d', $nid);
171 }
172 else {
173 db_query("INSERT INTO {node_template} (nid, is_template) VALUES (%d, %d)", $nid, 1);
174 }
175 drupal_goto('node/'.$nid);
176 }
177 else {
178 duplicate_node($form_values['nid']);
179 }
180 }
181 return '';
182 }
183
184 /**
185 * Clones a node
186 */
187 function duplicate_node($nid) {
188 if (is_numeric($nid)) {
189 global $user;
190
191 $existed_node = db_num_rows(db_query('SELECT * FROM {node_template} WHERE nid = %d', $nid));
192 if ($existed_node > 0) {
193 db_query('UPDATE {node_template} SET is_template = 1 WHERE nid = %d', $nid);
194 } else {
195 db_query("INSERT INTO {node_template} (nid, is_template) VALUES (%d, %d)", $nid, 1);
196 }
197
198 $parents = array();
199 $oldnode = node_load($nid);
200
201 if ($oldnode->type == "book") {
202 $pages = array();
203 $pages = book_tree_travel($nid,$pages,true);
204 //print_r($pages);
205 $first_time = true;
206 if (count($pages)>0 && variable_get('node_template_with_child', TRUE)) {
207 foreach ($pages as $ori_node){
208 $node = node_load($ori_node->nid,NULL,TRUE);
209 //watchdog('content', t('node_duplicate: duplicating %subject.', array('%subject' => theme('placeholder', $ori_node->nid))), WATCHDOG_WARNING);
210 if (isset($node->nid)) {
211
212 $node->nid = NULL;
213 $node->uid = $user->uid;
214 $node->created = 0;
215 $node->menu = NULL;
216 $node->path = NULL;
217
218 if ($first_time) {
219 $node->title = t('Clone of %title', array('%title' => $node->title));
220 $first_time = false;
221 }
222
223 if (variable_get('clone_reset_'. $node->type, FALSE)) {
224 $node_options = variable_get('node_options_'. $node->type, array('status', 'promote'));
225 // fill in the default values
226 foreach (array('status', 'moderate', 'promote', 'sticky', 'revision') as $key) {
227 $node->$key = in_array($key, $node_options);
228 }
229 }
230 node_save($node);
231 $parents[$ori_node->nid] = $node->nid;
232 }
233 }
234 reset($parents);
235 foreach ($parents as $old_node_id => $node_id){
236 //watchdog('content', t('node_duplicate: updating %subject.', array('%subject' => theme('placeholder', $node_id))), WATCHDOG_WARNING);
237 $newnode = node_load($node_id,NULL,TRUE);
238 if (array_key_exists($newnode->parent, $parents)){
239 $newnode->parent = $parents[$newnode->parent];
240 book_update($newnode);
241 }
242 }
243 }
244
245 reset($parents);
246 drupal_goto('node/'. current($parents).'/edit');
247
248 }
249 else {
250
251 if (isset($oldnode->nid)) {
252 $oldnode->nid = NULL;
253 $oldnode->uid = $user->uid;
254 $oldnode->created = 0;
255 $oldnode->menu = NULL;
256 $oldnode->path = NULL;
257 $oldnode->title = t('Clone of %title', array('%title' => $oldnode->title));
258
259 if (variable_get('clone_reset_'. $oldnode->type, FALSE)) {
260 $node_options = variable_get('node_options_'. $oldnode->type, array('status', 'promote'));
261 // fill in the default values
262 foreach (array('status', 'moderate', 'promote', 'sticky', 'revision') as $key) {
263 $oldnode->$key = in_array($key, $node_options);
264 }
265 }
266 node_save($oldnode);
267 drupal_goto('node/'. $oldnode->nid.'/edit');
268 }
269 }
270 }
271 }
272
273 /**
274 * find all the children of a book node
275 */
276 function book_tree_travel($nid, $pages = array(), $include_father = false) {
277 if ($include_father) {
278 $result = db_query(db_rewrite_sql('SELECT n.nid FROM {node} n WHERE n.nid = %d AND n.moderate = 0'), $nid);
279 while ($page = db_fetch_object($result)) {
280 $pages[] = $page;
281 }
282 }
283
284 $children = db_query(db_rewrite_sql('SELECT n.nid FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.status = 1 AND b.parent = %d AND n.moderate = 0'), $nid);
285 while ($childpage = db_fetch_object($children)) {
286 $pages[] = $childpage;
287 $pages = book_tree_travel($childpage->nid, $pages);
288 }
289
290 return $pages;
291 }
292
293 /********************************************************************
294 * Module Functions :: Controllers
295 ********************************************************************/
296
297 function nodetemplate_admin() {
298 global $user;
299
300 $title = t('Node template') . ' : ' . $user->name;
301 drupal_set_title($title);
302 $output = nodetemplate_list();
303 return $output;
304 }
305
306 /**
307 * The configuration page.
308 */
309 function nodetemplate_configure() {
310 global $user;
311 $form = array();
312 $form['maxnodes'] = array(
313 '#type' => 'textfield',
314 '#title' => t('Number of items'),
315 '#description' => t('Maximum number of items to display.'),
316 '#default_value' => $user->nodetemplate ? $user->nodetemplate['default']['maxnodes'] : 50,
317 '#size' => 4
318 );
319
320 $form['submit'] = array(
321 '#type' => 'submit',
322 '#value' => t('Save configuration')
323 );
324 $output = drupal_get_form('nodetemplate_configure', $form);
325 drupal_set_title(t('Node template : %username', array('%username' => $user->name)));
326 return $output;
327 }
328
329 function nodetemplate_configure_validate($form_id, $edit) {
330 if (!is_numeric($edit['maxnodes'])) {
331 form_set_error('maxnodes', t('Please enter a numeric value.'));
332 }
333 }
334
335 function nodetemplate_configure_submit($form_id, $edit) {
336 global $user;
337 if (!isset($user->nodetemplate)) {
338 $user->nodetemplate = array();
339 }
340 $user->nodetemplate['default']['maxnodes'] = $edit['maxnodes'];
341
342 user_save($user, array('nodetemplate' => $user->nodetemplate));
343 drupal_set_message(t('The node template configuration has been saved.'));
344 return 'nodetemplate';
345 }
346
347 /********************************************************************
348 * Module Functions :: Views
349 ********************************************************************/
350
351 /**
352 * The default admin interface is a list of content.
353 */
354 function nodetemplate_list() {
355 global $user;
356 $maxnodes = isset($user->nodetemplate) ? $user->nodetemplate['default']['maxnodes'] : 50;
357
358 if (!is_numeric($maxnodes)) {$maxnodes = 50;}
359
360
361 $node_select = array('n.nid', 'n.uid', 'n.type', '0 AS cid', 'n.title', 'n.status', 'n.changed', '1 AS node');
362 $node_from = array('{node} n');
363 $node_join = array('INNER JOIN {node_template} s ON n.nid = s.nid');
364 $node_where = array('s.is_template = 1');
365
366 $sql = 'SELECT '. implode(', ', $node_select) .' FROM '. implode(', ', $node_from) .' '. implode(' ', $node_join) .' WHERE '. implode(' ', $node_where);
367 $count_sql = 'SELECT COUNT(n.nid) FROM '. implode(', ', $node_from) .' '. implode(' ', $node_join) .' WHERE '. implode(' ', $node_where);
368
369 // build the combined template listing
370 $header = array(
371 array('data' => t('Type'), 'field' => 'type'),
372 array('data' => t('Title'), 'field' => 'title'),
373 array('data' => t('Owner'), 'field' => 'uid'),
374 array('data' => t('Published'), 'field' => 'status'),
375 array('data' => t('Modified'), 'field' => 'changed', 'sort' => 'desc'),
376 array('data' => t('Operations'), 'colspan' => 2)
377 );
378
379 $result = pager_query($sql . tablesort_sql($header), $maxnodes, 0, $count_sql);
380 $yes = t('yes');
381 $no = t('no');
382
383 while ($row = db_fetch_object($result)) {
384 // it's a node
385 if ($row->node == 1) {
386 // Duplicate permissions are set by the nodetype's access hook.
387 // This approach is part of Drupal's core design.
388 $can_duplicate = FALSE;
389
390 //Check the nodetype's access hook.
391 $function = $row->type. '_access';
392 if ($flexinode_enabled && strstr($function, 'flexinode-')) {
393 $function = 'flexinode_access';
394 }
395 elseif ($cck_enabled && strstr($function, 'content_')) {
396 $function = 'content_access';
397 }
398
399 if (function_exists($function)) {
400 $can_duplicate = $function('update', $row) ? TRUE : FALSE;
401 }
402
403 // the name of the owner of this node
404 $name = ($user->uid == $row->uid) ? $user->name : db_result(db_query('SELECT name FROM {users} WHERE uid = %d', $row->uid));
405 $rows[] = array(
406 node_get_name($row->type),
407 l($row->title, "node/$row->nid"),
408 $name,
409 $row->status ? $yes : $no,
410 format_date($row->changed, 'small'),
411 $can_duplicate ? l(t('duplicate'), "node/$row->nid/template") : '',
412 l(t('delete'), "nodetemplate/delete/$row->nid")
413 );
414 }
415 }
416
417 if ($rows) {
418 $pager = theme('pager', NULL, $maxnodes, 0);
419 if (!empty($pager)) {
420 $rows[] = array(array('data' => $pager, 'colspan' => 8));
421 }
422 $output .= theme('table', $header, $rows);
423 }
424 else {
425 $output .= t('You have no node template yet.');
426 }
427
428 return $output;
429 }
430
431 /**
432 * The deletion menu callback
433 */
434 function nodetemplate_delete() {
435 $nid = intval(arg(2));
436 if (is_numeric($nid)) {
437 db_query('DELETE FROM {node_template} WHERE nid = %d', $nid);
438 }
439 drupal_goto('nodetemplate');
440 }

  ViewVC Help
Powered by ViewVC 1.1.2