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

Contents of /contributions/modules/stage/stage.module

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


Revision 1.3 - (show annotations) (download) (as text)
Wed Jul 2 15:55:08 2008 UTC (16 months, 3 weeks ago) by daryl
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +24 -1 lines
File MIME type: text/x-php
module needs to turn on revisions for specified types
1 <?php
2 // $Id: stage.module,v 1.2 2008/07/02 15:09:55 daryl Exp $
3
4 /**
5 * Implementation of hook_help().
6 */
7 function stage_help($section) {
8 switch ($section) {
9 case 'admin/settings/stage':
10 case 'admin/help#stage':
11 return '<p>' . t('Stage site changes in a queue to be pushed in batches. Changes are visible only on specified staging servers.') . '</p>';
12 }
13 }
14
15
16 /**
17 * Implementation of hook_nodeapi().
18 */
19 function stage_nodeapi(&$node, $op, $a, $b){
20 $dev_hosts = split(',', str_replace(array(' ', "\n"), array('', ''), variable_get('stage_dev_hosts', '')));
21 $production_hosts = split(',', str_replace(array(' ', "\n"), array('', ''), variable_get('stage_production_hosts', '')));
22
23 //Strip out port if there is one. (Maybe make this an option?)
24 $_SERVER['HTTP_HOST'] = preg_replace('/:\d*$/', '', $_SERVER['HTTP_HOST']);
25 $is_stage_host = in_array($_SERVER['HTTP_HOST'], $dev_hosts);
26 $is_production_host = in_array($_SERVER['HTTP_HOST'], $production_hosts);
27 $stage_force_types = variable_get('stage_force_types', array());
28
29 if($is_stage_host && array_key_exists($node->type, $stage_force_types) && $node->type === $stage_force_types[$node->type]){
30 switch($op){
31 case 'insert':
32 case 'update':
33 $result = db_fetch_object(db_query('SELECT vid FROM {stage_queue} WHERE nid = %d', $node->nid));
34 if($result->vid > 0){
35 $status = db_query('UPDATE {node} SET vid = %d WHERE nid = %d', $result->vid, $node->nid);
36 $status = db_query('UPDATE {stage_queue} SET sid = %d WHERE nid = %d', stage_get_queue_id(), $node->nid);
37 if($status === false){
38 drupal_set_message(t('Error updating node table for stage module'));
39 }
40 }
41 else{
42 $vid = 0;
43 $result = db_query('SELECT vid FROM {node_revisions} WHERE nid = %d ORDER BY vid DESC LIMIT 2', $node->nid);
44 while($row = db_fetch_object($result)){
45 $vid = $row->vid;
46 }
47 if($vid > 0){
48 $status = db_query('UPDATE {node} SET vid = %d WHERE nid = %d', $vid, $node->nid);
49 $status2 = db_query('INSERT INTO {stage_queue} (sid, nid, vid, time) VALUES(%d, %d, %d, NOW())', stage_get_queue_id(), $node->nid, $vid);
50
51 if($status === false || $status2 === false){
52 drupal_set_message(t('Error updating node or stage_queue table for stage module'));
53 }
54 }
55 }
56 break;
57 case 'alter':
58 if($node->nid > 0){
59 $result = db_fetch_object(db_query('SELECT MAX(vid) AS vid FROM {node_revisions} WHERE nid = %d', $node->nid));
60 $node = node_load($node->nid, $result->vid, true);
61 $node = node_prepare($node, false);
62 }
63 break;
64 //Load is being called after alter and view and is overwriting the title set thereby.
65 //Here we force it.
66 case 'load':
67 $result = db_fetch_object(db_query('SELECT title FROM {node_revisions} WHERE nid = %d ORDER BY vid DESC LIMIT 1', $node->nid));
68 $node->title = $result->title;
69 break;
70 }
71 }
72 //is production host
73 else{
74 switch($op){
75 //Force add/edit forms on non-dev urls to go to an equivalent dev url
76 case 'prepare':
77 if(array_key_exists($node->type, $stage_force_types) && $node->type === $stage_force_types[$node->type]){
78 $base_root = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
79 $base_url = $base_root .= '://'. preg_replace('/[^a-z0-9-:._]/i', '', $dev_hosts[0]);
80 // $_SERVER['SCRIPT_NAME'] can, in contrast to $_SERVER['PHP_SELF'], not
81 // be modified by a visitor.
82 if ($dir = trim(dirname($_SERVER['SCRIPT_NAME']), '\,/')) {
83 $base_path = "/$dir";
84 $base_url .= $base_path;
85 $base_path .= '/';
86 }
87 if($_SERVER['QUERY_STRING']){
88 $base_url .= '?' . $_SERVER['QUERY_STRING'];
89 }
90 header('Location: ' . $base_url);
91 }
92 break;
93 }
94 }
95 //print "$op<br />";
96 }
97
98
99 function stage_get_queue_id(){
100 $stage_id = db_fetch_object(db_query('SELECT MAX(sid) AS sid FROM {stage_deployment}'));
101 return $stage_id->sid;
102 }
103
104 /**
105 * Implementation of hook_menu().
106 */
107 function stage_menu($may_cache) {
108 $items = array();
109 if ($may_cache) {
110 $items[] = array(
111 'path' => 'admin/settings/stage',
112 'title' => t('Stage'),
113 'callback' => 'drupal_get_form',
114 'callback arguments' => array('stage_admin_settings'),
115 'access' => user_access('administer site configuration'),
116 'description' => t('Stage site changes in a queue to be pushed in batches. Changes are visible only on specified staging servers.'),
117 'type' => MENU_NORMAL_ITEM
118 );
119 $items[] = array(
120 'path' => 'admin/settings/stage/push',
121 'title' => t('Production Push'),
122 'callback' => 'drupal_get_form',
123 'callback arguments' => array('stage_push_form'),
124 'access' => user_access('administer site configuration'),
125 'type' => MENU_LOCAL_TASK
126 );
127 $items[] = array(
128 'path' => 'admin/settings/stage/list',
129 'title' => t('List Deployment Batches'),
130 'callback' => 'stage_list_batches',
131 'access' => user_access('administer site configuration'),
132 'type' => MENU_LOCAL_TASK
133 );
134 }
135
136 //drupal_add_css(drupal_get_path('module', 'stage') .'/stage.css');
137 //drupal_add_js(drupal_get_path('module', 'stage') .'/stage.js');
138
139 return $items;
140 }
141
142 function stage_list_batches(){
143 $num = arg(4);
144 if($num > 0){
145 $header = array(t('Title'), t('User'), t('Date'));
146 $rows = array();
147
148 $result = db_query('SELECT r.nid, r.vid, u.name as user_name, r.title, s.time FROM {node_revisions} as r, {users} as u, {stage_queue} as s WHERE s.vid = r.vid AND u.uid = r.uid AND s.sid = %d', $num);
149 while($row = db_fetch_object($result)){
150 $rows[] = array(
151 l($row->title, 'node/' . $row->nid . '/revisions/' . $row->vid . '/view'),
152 $row->user_name,
153 $row->time
154 );
155 }
156 return theme('table', $header, $rows);
157 }
158 else{
159 $header = array(t('Deployment'), t('User'), t('Date'));
160 $rows = array();
161 $result = db_query('SELECT sid, name, uid, time_pushed FROM {stage_deployment} ORDER BY time_pushed DESC, name');
162 while($row = db_fetch_object($result)){
163 if($row->name == ''){
164 $row->name = t('!Pending');
165 }
166 $rows[] = array(
167 l($row->name, 'admin/settings/stage/list/' . $row->sid),
168 $row->uid,
169 $row->time_pushed
170 );
171 }
172 return theme('table', $header, $rows);
173 }
174 }
175
176 function stage_push_form(){
177 if(user_access('push stage changes')){
178 $form['name'] = array('#type' => 'textfield',
179 '#title' => t('Deployment Name'),
180 '#description' => t('Specify a name for this deployment (e.g. "milestone X".'),
181 '#required' => true
182 );
183 $form['push'] = array('#type' => 'submit',
184 '#value' => t('Push Content into Production'),
185 '#description' => t('Press this button to push the current set of changes into the production database.')
186 );
187 }
188 return $form;
189 }
190
191 function stage_push_form_submit(){
192 global $user;
193 if(user_access('push stage changes')){
194 $errors = array();
195 $id = stage_get_queue_id();
196 db_query('UPDATE {stage_deployment} SET uid = %d, name = "%s" WHERE sid = %d', $user->uid, $_POST['name'], $id);
197 db_query('INSERT INTO {stage_deployment} (sid) VALUES(%d)', ($id + 1));
198 $result = db_query('SELECT nid FROM {stage_queue} WHERE sid = %d', $id);
199 while($row = db_fetch_object($result)){
200 $status = db_query('UPDATE {node} SET vid = (SELECT MAX(vid) FROM {node_revisions} WHERE nid = %d) WHERE nid = %d', $row->nid, $row->nid);
201 $status2 = db_query('UPDATE {stage_queue} SET vid = (SELECT MAX(vid) FROM {node_revisions} WHERE nid = %d) WHERE nid = %d', $row->nid, $row->nid);
202 if($status === false || $status2 === false){
203 $errors[] = $row->nid;
204 }
205 }
206 if(count($errors) > 0){
207 drupal_set_message('There were errors updating the following nodes: ' . join(', ', $errors) . ' for staging queue number ' . $id . '.');
208 }
209 else{
210 drupal_set_message('Staging queue number ' . $id . ' was pushed into production.');
211 }
212 }
213 }
214
215 /**
216 * Implementation of hook_perm().
217 */
218 function stage_perm() {
219 return array('push stage changes');
220 }
221
222
223 /**
224 * Implementation of hook_form_alter().
225 */
226 function stage_form_alter($form_id, &$form, $key_in = NULL) {
227 }
228
229
230
231 function stage_admin_settings() {
232
233 $form['stage_production_hosts'] = array('#type' => 'textarea',
234 '#title' => t('Production Hosts'),
235 '#default_value' => variable_get('stage_production_hosts', ''),
236 '#description' => t('Enter a list of production hosts that should not display staged content, comma-separated.')
237 );
238
239 $form['stage_dev_hosts'] = array('#type' => 'textarea',
240 '#title' => t('Development Hosts'),
241 '#default_value' => variable_get('stage_dev_hosts', ''),
242 '#description' => t('Enter a list of development hosts that should display staged content and from which content can be staged, comma-separated.')
243 );
244
245 $stage_force_types = array();
246 foreach(node_get_types() as $k => $v){
247 $stage_force_types[$k] = $v->name;
248 }
249 $form['stage_force_types'] = array('#type' => 'checkboxes',
250 '#title' => t('Staging Types'),
251 '#default_value' => variable_get('stage_force_types', ''),
252 '#options' => $stage_force_types,
253 '#description' => t('The checked types are the only types that can be staged. Navigating to the add or edit form for these nodes will cause a redirection to a staging server.')
254 );
255
256 return system_settings_form($form);
257 }
258
259 /**
260 * Writing custom function here because we need to do more than just save the
261 * submitted values. (We also turn on the revision flag for each type specified.
262 */
263
264 function stage_admin_settings_submit(){
265 variable_set('stage_dev_hosts', $_POST['stage_dev_hosts']);
266 variable_set('stage_production_hosts', $_POST['stage_production_hosts']);
267 variable_set('stage_force_types', $_POST['stage_force_types']);
268
269 //Be sure to turn on revisions for all specified types.
270 foreach($_POST['stage_force_types'] as $type){
271 $val = variable_get('node_options_' . $type, array());
272
273 if(!in_array('revision', $val)){
274 $val[] = 'revision';
275 }
276 variable_set('node_options_' . $type, $val);
277 }
278 drupal_set_message(t('Stage settings saved.'));
279 }
280
281
282 /**
283 * Implementation of hook_forms().
284 */
285 function stage_forms() {
286 $forms = array();
287 if (user_access('access devel information')) {
288 // registers each devel_reinstall_$module form_id
289 $modules = module_list();
290 foreach ($modules as $module) {
291 $forms['devel_reinstall_'. $module]['callback'] = 'devel_reinstall_form';
292 }
293 }
294 return $forms;
295 }
296

  ViewVC Help
Powered by ViewVC 1.1.2