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

Contents of /contributions/modules/crossite/crossite.module

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


Revision 1.6 - (show annotations) (download) (as text)
Thu Jun 7 03:53:28 2007 UTC (2 years, 5 months ago) by hanenkamp
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +7 -5 lines
File MIME type: text/x-php
Further refined the redirect so that it works a little more consistently.
1 <?php
2 /* $Id: crossite.module,v 1.2 2007/05/16 02:52:03 hanenkamp Exp $ */
3
4 // This is a Drupal module for allowing a person to share nodes across a
5 // Drupal "multi-site" install. This can be done natively from Drupal without
6 // any help from this module.
7 //
8 // This module helps categorize shared nodes in a multi-site configuration
9 // using taxonomy.
10
11 /**
12 * Returns a list of available configuration paths. This is done by finding
13 * all the directory names under ./sites, excluding "all".
14 *
15 * @return
16 * An array of configuration paths that can be used to locate settings files.
17 */
18 function crossite_get_all_sites() {
19 $files = file_scan_directory('./sites', '.*', array('.', '..', 'CVS', '.svn', 'all'), 0, FALSE);
20 $keys = array_keys($files);
21 array_walk($keys, create_function('&$str', '$str = substr($str, 8);'));
22
23 return $keys;
24 }
25
26 /**
27 * Returns the name of the current site being used. This is derived from the
28 * output of conf_path(), there may be a better way to do this.
29 *
30 * @return
31 * The name of the site config directory, which is used to lookup values in
32 * the crossite_tids and crossite_bases settings. The return value is just the
33 * file name and does not include the sites component.
34 */
35 function crossite_get_current_site() {
36 $conf_path = conf_path();
37 return substr($conf_path, 6);
38 }
39
40 /**
41 * Returns the base URL for the named site. The $base_url variable must be set
42 * correctly in each of the site configuration files.
43 *
44 * This function caches the result so that it doesn't need to be calculated
45 * more than once. It is assumed that a given site's base URL does not change.
46 * If you change the base URL of a given site, you should make sure to empty the
47 * cache table in the database so this value will be recalculated.
48 *
49 * @param $site
50 * The site to retrieve the base URL of. If not given, assumes 'default'.
51 *
52 * @return
53 * The absolute base URL of the site named by the configuration path.
54 */
55 function crossite_get_base_url($site = 'default') {
56 $site_cache = 'crossite_base_url[' . $site . ']';
57 if ($cached = cache_get($site_cache, 'cache')) {
58 return $cached->data;
59 }
60
61 include './sites/' . $site . '/settings.php';
62 cache_set($site_cache, 'cache', $base_url, CACHE_PERMANENT);
63 return $base_url;
64 }
65
66 function crossite_mapping() {
67 $tids = array();
68
69 if ($cached = cache_get('crossite_tids')) {
70 $tids = unserialize($cached->data);
71 }
72
73 else {
74 $result = db_query('SELECT tid, conf_path FROM {crossite_domains_tids}');
75 while ($row = db_fetch_object($result)) {
76 $tids[ $row->tid ] = $row->conf_path;
77 }
78 cache_set('crossite_tids', 'cache', serialize($tids), CACHE_TEMPORARY);
79 }
80
81 return $tids;
82 }
83
84 /**
85 * Implements hook_view(). If the node being viewed does not belong to this site
86 * and the crossite_redirect option is set to TRUE, then a this implementation
87 * will cause a redirect to be performed. The redirect will go to either the
88 * site that the node belongs to or to the default site if it belongs to no
89 * particular site. If this site is the default site, then no redirect will be
90 * performed if the redirect would return to this site.
91 */
92 function crossite_nodeapi(&$node, $op, $extra = NULL, $page = FALSE) {
93 switch($op) {
94 case 'load':
95 $tids = crossite_mapping();
96
97 $sites = array();
98 $terms = taxonomy_node_get_terms($node->nid);
99
100 // Find all the sites that match the node
101 foreach ($tids as $tid => $conf_path) {
102
103 if (array_key_exists($tid, $terms)) {
104 $sites[$conf_path] = 1;
105 }
106 }
107
108 // Add 'default' if no other site matched
109 if (empty($sites)) {
110 $sites['default'] = 1;
111 }
112
113 // Set the 'sites' to just the keys
114 return array( 'sites' => array_keys($sites) );
115
116 case 'view':
117 // No redirect unless this is the node's very own page
118 if (!$page) {
119 return;
120 }
121
122 // Lookup this site
123 $this_site = crossite_get_current_site();
124
125 // Use the sites associated with the node during load. However, do NOT
126 // assume that it hasn't been tampered with. If this array comes out empty,
127 // make sure to drop 'default' back into it. This will help to prevent a
128 // redirect cycle.
129 $sites = !empty($node->sites) ? $node->sites : array('default');
130
131 // This node belongs to the current site: do not redirect
132 if (in_array($this_site, $sites)) {
133 return;
134 }
135
136 // Otherwise, go to the first site in the list
137 $to_site = $sites[0];
138 $base_url = crossite_get_base_url($to_site);
139
140 // This error occurs when crossite_tids is setup, but crossite_bases
141 // is not.
142 if (!isset($base_url)) {
143 watchdog('crossite',
144 t('The crossite configuration indicates a redirect to %site, but no '.
145 'base URL was found for to get there. You need to edit the settings.php '.
146 'file for that site.',
147 array(
148 '%site' => $to_site,
149 )), WATCHDOG_ERROR);
150
151 // An error, but we can show the node as is.
152 return;
153 }
154
155 // Get the base URL and use it to construct a redirect.
156 $query_string = array();
157 parse_str($_SERVER['QUERY_STRING'], $query_string);
158 if (isset($query_string['q'])) {
159 unset($query_string['q']);
160 }
161
162 $rel_url = url('node/'.$node->nid);
163 header('HTTP/1.1 301 Moved Permanently');
164 header('Location: '.$base_url.'/?q=node/'.$node->nid, http_build_query($query_string));
165 exit;
166 }
167 }
168
169 /**
170 * Implements hook_menu().
171 */
172 # function crossite_menu($may_cache) {
173 # $items = array();
174 #
175 # # if ($may_cache) {
176 # # $items[] = array(
177 # # 'path' => 'admin/content/crossite',
178 # # 'title' => t('Crossite Terms'),
179 # # 'access' => user_access('administer crossite'),
180 # # 'callback' => 'crossite_admin_terms',
181 # # 'type' => MENU_NORMAL_ITEM,
182 # # );
183 # # }
184 # #
185 # # else {
186 # # if (arg(0) == 'admin' && arg(1) == 'content' && arg(2) == 'crossite' && is_numeric(arg(3))) {
187 # # $did = arg(3);
188 # # $items[] = array(
189 # # 'path' => 'admin/content/crossite/new'
190 # # 'title' => t('Add'),
191 # # 'access' => user_access('administer crossite'),
192 # # 'callbak' =>
193 # #
194 # # }
195 #
196 # return $items;
197 # }
198
199 /**
200 * Provides a form for administering terms.
201 */
202 # function crossite_admin_terms() {
203 # $header = array(
204 # array('data' => t('Term'), 'field' => 'name'),
205 # array('data' => t('Site'), 'field' => 'conf_path'),
206 # );
207 #
208 # $sql = '
209 # SELECT did, name, conf_path
210 # FROM {crossite_domains_tids} c INNER JOIN {term_data} t ON c.tid = t.tid';
211 # $sql .= tablesort_sql($header);
212 # $result = pager_query($sql, 20);
213 #
214 # while ($domain_tid = db_fetch_object($result)) {
215 # $rows[] = array(
216 # l($domain_tid->name, 'admin/content/crossite/'.$domain_tid->did),
217 # $domain_tid->conf_path,
218 # );
219 # }
220 #
221 # if (count($rows)) {
222 # $output = theme('table', $header, $rows);
223 #
224 # $pager = theme('pager', NULL, 20, 0);
225 # if (!empty($pager)) {
226 # $output .= $pager;
227 # }
228 # }
229 #
230 # else {
231 # $output .= '<p>'.t('No term has been linked with a site.').'</p>';
232 # }
233 #
234 # return $output;
235 # }
236
237 function crossite_form_alter($form_id, &$form) {
238 if ($form_id == 'taxonomy_form_term' && user_access('administer crossite')) {
239 // Can't use weight because it either puts the extra bits of the form
240 // above everything, after Name, or after Submit. I want it after Weight and
241 // before submit.
242 $form_keys = array_keys($form);
243 $submit_index = array_search('submit', $form_keys);
244 $form_start = array_splice($form, 0, $submit_index);
245
246 $all_sites = crossite_get_all_sites();
247 $available_conf_paths = array_combine($all_sites, $all_sites);
248
249 if (isset($form['#parameters'][2]['tid'])) {
250 $result = db_query("
251 SELECT conf_path
252 FROM {crossite_domains_tids}
253 WHERE tid = %d", $form['#parameters'][2]['tid']);
254
255 while ($conf = db_fetch_array($result)) {
256 $current_settings[] = $conf['conf_path'];
257 }
258 }
259
260 $crossite_form['crossite_fieldset'] = array(
261 '#type' => 'fieldset',
262 '#title' => t('Crossite Settings'),
263 '#collapsible' => TRUE,
264 '#collapsed' => TRUE,
265 );
266
267 $crossite_form['crossite_fieldset']['crossite_conf_path'] = array(
268 '#type' => 'checkboxes',
269 '#title' => t('Nodes with this term belong to the selected sites'),
270 '#description' => t('If none are checked, this term does not modify site membership.'),
271 '#default_value' => $current_settings,
272 '#options' => $available_conf_paths,
273 );
274
275 $form = array_merge($form_start, $crossite_form, $form);
276 }
277 }
278
279 function crossite_taxonomy($op, $type, $form_values = NULL) {
280 if ($type == 'term') {
281 if ($op == 'insert' || $op == 'update') {
282 $tid = $form_values['tid'];
283 $crossite_conf_path = $form_values['crossite_conf_path'];
284
285 db_query('DELETE FROM {crossite_domains_tids} WHERE tid = %d', $tid);
286
287 foreach ($crossite_conf_path as $conf_path) {
288 if ($conf_path) {
289 $result = db_query("INSERT INTO {crossite_domains_tids}(tid, conf_path) VALUES (%d, '%s')", $tid, $conf_path);
290 }
291 }
292 }
293
294 else {
295 db_query('DELETE FROM {crossite_domains_tids} WHERE tid = %d', $tid);
296 }
297
298 // Update the cache
299 cache_clear_all('crossite_tids');
300 crossite_mapping();
301 }
302 }
303
304 ?>

  ViewVC Help
Powered by ViewVC 1.1.2