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

Contents of /contributions/modules/joomla/joomla.module

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


Revision 1.16 - (show annotations) (download) (as text)
Tue Jul 7 10:13:09 2009 UTC (4 months, 3 weeks ago) by malclocke
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--1
Changes since 1.15: +157 -39 lines
File MIME type: text/x-php
feature request #489732 by malclocke: Allow users to log in to Drupal site with their Joomla password
1 <?php
2 // $Id: joomla.module,v 1.15 2009/07/07 09:48:53 malclocke Exp $
3
4 /**
5 * @file
6 * The joomla module used for migrate Joomla to Drupal.
7 */
8
9 /**
10 * Implementation of hook_help().
11 */
12 function joomla_help($path, $arg) {
13 switch ($path) {
14 case 'admin/help#joomla':
15 $output = "The joomla module used for migrate Joomla to Drupal.";
16 return $output;
17 case 'admin/modules#description':
18 return 'The joomla module used for migrate Joomla to Drupal.';
19 }
20 }
21
22 /**
23 * Implementation of hook_perm
24 */
25 function joomla_perm() {
26 return array('access joomla', 'administer joomla');
27 }
28
29 /**
30 * Menu callback. Prints a listing of active nodes on the site.
31 */
32
33 function joomla_menu() {
34 $items = array();
35
36 $items['joomla/import/user'] = array(
37 'title' => 'Joomla user import',
38 'page callback' => 'joomla_import',
39 'page arguments' => array('user'),
40 'access arguments' => array('administer joomla'),
41 'type' => MENU_CALLBACK
42 );
43
44 $items['joomla/import/section'] = array(
45 'title' => 'Joomla section import',
46 'page callback' => 'joomla_import',
47 'page arguments' => array('section'),
48 'access arguments' => array('administer joomla'),
49 'type' => MENU_CALLBACK
50 );
51
52 $items['joomla/import/content'] = array(
53 'title' => 'Joomla content import',
54 'page callback' => 'joomla_import',
55 'page arguments' => array('content'),
56 'access arguments' => array('administer joomla'),
57 'type' => MENU_CALLBACK
58 );
59
60 $items['admin/settings/joomla'] = array(
61 'title' => 'Joomla to Drupal',
62 'page callback' => 'drupal_get_form',
63 'page arguments' => array('joomla_admin_settings'),
64 'access arguments' => array('administer joomla'),
65 'description' => 'Migrate Joomla to Drupal.'
66 );
67
68
69 return $items;
70 }
71
72
73 function joomla_admin_settings() {
74
75 // only administrators can access this function
76
77 // Generate the form - settings applying to all patterns first
78 $form['joomla_settings'] = array(
79 '#type' => 'fieldset',
80 '#weight' => -20,
81 '#title' => t('Joomla to Drupal'),
82 '#collapsible' => FALSE,
83 '#collapsed' => FALSE,
84 '#description' => "Click below link to Import Joomla Table to Drupal:"
85 ."<ul>"
86 ."<li/>".l(t('Import Joomla Users'), "joomla/import/user")
87 ."<li/>".l(t('Import Joomla Sections & Categories'), "joomla/import/section")
88 ."<li/>".l(t('Import Joomla Contents and Static Contents'), "joomla/import/content")
89 ."</ul>"
90 ."<br/><br/><b>IMPORTANT!</b>"
91 ."<ol><li/>You must save below settings before click the Import links above!"
92 ."<li/>You must enable <b>Profiles module</b>"
93 ."</ol>"
94 );
95
96 $form['joomla_settings_database'] = array(
97 '#type' => 'fieldset',
98 '#weight' => -20,
99 '#title' => t('Joomla settings'),
100 '#collapsible' => TRUE,
101 '#collapsed' => FALSE
102 );
103
104 $form['joomla_settings_database']['joomla_database'] = array(
105 '#type' => 'textfield',
106 '#title' => 'Database name of Joomla',
107 '#default_value' => variable_get('joomla_database', 'joomla'),
108 '#description' => 'Database name of Joomla'
109 );
110
111 $form['joomla_settings_database']['joomla_prefix'] = array(
112 '#type' => 'textfield',
113 '#title' => 'Table Prefix of Joomla',
114 '#default_value' => variable_get('joomla_prefix', 'jos_'),
115 '#description' => 'Table Prefix of Joomla'
116 );
117
118 $form['joomla_settings_database']['joomla_path'] = array(
119 '#type' => 'textfield',
120 '#title' => 'Path of your Joomla instalation',
121 '#default_value' => variable_get('joomla_path', '/home/your_username/public_html/joomla'),
122 '#description' => "The path name where you install Joomla. Example:<br/>"
123 ."<ul><li/>Apache: <b>/home/YOUR_USERNAME/public_html/joomla</b>"
124 ."<li/>Windows using WAMP: <b>c:/wamp/www/joomla</b>"
125 ."<li/>Windows using IIS: <b>C:/Inetpub/wwwroot/joomla</b></ul>"
126 );
127
128 $form['joomla_settings_advanced'] = array(
129 '#type' => 'fieldset',
130 '#weight' => -20,
131 '#title' => t('Drupal settings'),
132 '#collapsible' => TRUE,
133 '#collapsed' => FALSE
134 );
135
136 $form['joomla_settings_advanced']['joomla_delay_row'] = array(
137 '#type' => 'textfield',
138 '#title' => 'Number of imported rows before delay',
139 '#default_value' => variable_get('joomla_delay_row', '100'),
140 '#description' => "How many rows will be imported before this module add delay, see below option."
141 );
142
143 $form['joomla_settings_advanced']['joomla_delay_sec'] = array(
144 '#type' => 'textfield',
145 '#title' => 'Delay before process next batch records (in second)',
146 '#default_value' => variable_get('joomla_delay_sec', '1'),
147 '#description' => "If you import huge amount of Joomla-contents then you need to increase this DELAY to avoid timeout."
148 );
149
150 $form['joomla_settings_advanced']['joomla_input_format'] = array(
151 '#type' => 'radios',
152 '#title' => 'Input Format',
153 '#default_value' => variable_get('joomla_input_format', 2),
154 '#options' => array(
155 "Filtered HTML", "PHP code", "Full HTML"),
156 '#description' => 'Select Input Format to apply to all imported contents.'
157 );
158
159 $form['joomla_settings_advanced']['joomla_update_duplicate'] = array(
160 '#type' => 'radios',
161 '#title' => 'If found Duplicate items',
162 '#default_value' => variable_get('joomla_update_duplicate', 0),
163 '#options' => array(
164 "Do not import",
165 "Replace duplicate items"),
166 '#description' => "Caution! If you select 'Replace duplicate items' then this module will replace existing items with new one. This options usefull if you do update in Joomla and want to do update in Drupal too."
167 );
168
169 $form['joomla_settings_advanced']['joomla_img_folder'] = array(
170 '#type' => 'textfield',
171 '#title' => 'Image/Picture folder',
172 '#default_value' => variable_get('joomla_img_folder', 'images'),
173 '#description' => "A folder to save any images from Joomla contents. This folder related to Drupal 'files' folder, i.e: if you enter '<b>images</b>' then all imported images will be save to Drupal '<b>files/images</b>'."
174 );
175
176 return system_settings_form($form);
177 }
178
179 function joomla_import($import_type) {
180 $joomla_database = variable_get('joomla_database', 'joomla');
181 $joomla_prefix = variable_get('joomla_prefix', 'jos_');
182
183 $joomla_delay_row = variable_get('joomla_delay_row', '100');
184 $joomla_delay_sec = variable_get('joomla_delay_sec', '1');
185 $joomla_update_duplicate = variable_get('joomla_update_duplicate', '0');
186 $joomla_img_folder = variable_get('joomla_img_folder', '0');
187 $joomla_path = variable_get('joomla_path', 'public_html/joomla');
188
189 $items_per_page = variable_get('default_nodes_main', 10);
190
191 $table_content = "$joomla_database.$joomla_prefix"."content";
192 $table_user = "$joomla_database.$joomla_prefix"."users";
193
194 switch($import_type) {
195 case 'user':
196 $output = "";
197 $output .= "<h2>Import Joomla Users</h2>";
198
199 if (!db_table_exists('{profile_fields}')) {
200 $output .= "Module Profile not yet installed.";
201 return $output;
202 }
203
204 //Add Realname to Profile
205 if(db_result(db_query("SELECT COUNT(*) FROM {profile_fields} WHERE name='profile_realname'")) == 0) {
206 db_query(" INSERT INTO {profile_fields} (title,name,type,weight) VALUES ('Real Name','profile_realname','textfield','0')");
207 }
208 $results_fid = db_query("SELECT fid from {profile_fields} WHERE name='profile_realname'");
209 $data_fid = db_fetch_object($results_fid);
210 $fid = $data_fid->fid;
211
212 //Check Users
213
214 $users_total = 0;
215 $users_updated = 0;
216 $users_new = 0;
217 $users_failed = 0;
218
219 $results_user = db_query("SELECT * FROM %s ORDER BY id", $table_user);
220
221 while ( $data = db_fetch_object($results_user) ) {
222 $users_total++;
223
224 $uid = db_result(db_query("SELECT uid FROM {joomla_users} WHERE juid = %d", $data->id));
225
226 // Check if the user has selected to update previously imported users
227 if ($uid && !$joomla_update_duplicate) {
228 continue;
229 }
230
231 $user = new stdClass();
232
233 // Set uid if we are updating an existing record
234 if ($uid) {
235 $user->uid = $uid;
236 }
237 $user->name = $data->username;
238 $user->mail = $data->email;
239 $user->status = !$data->block;
240 $user->created = strtotime($data->registerDate);
241 $user->access = strtotime($data->lastvisitDate);
242
243 /**
244 * Older versions of Joomla used an unsalted MD5 password hash. If this
245 * is the case we can use this hash as the Drupal password.
246 */
247 if (strlen($data->password) == 32) {
248 $user->pass = $data->password;
249 }
250
251 $res = FALSE;
252 if (!$uid) {
253 $res = drupal_write_record('users', $user);
254 }
255 elseif ($joomla_update_duplicate) {
256 $res = drupal_write_record('users', $user, 'uid');
257 }
258
259 if ($res) {
260 // Write into the joomla -> drupal user mapping table
261 $joomla_user = new stdClass();
262 $joomla_user->uid = $user->uid;
263 $joomla_user->juid = $data->id;
264 $joomla_user->password = $data->password;
265
266 // If this is set, than we can consider the users password converted
267 if (!empty($user->pass)) {
268 $joomla_user->converted = 1;
269 }
270
271 if ($uid) {
272 drupal_write_record('joomla_users', $joomla_user, 'uid');
273 }
274 else {
275 drupal_write_record('joomla_users', $joomla_user);
276 }
277
278 //Check and Update Realname
279 $profile_value = new stdClass();
280 $profile_value->fid = $fid;
281 $profile_value->uid = $user->uid;
282 $profile_value->value = $data->realname;
283
284 if ($uid) {
285 drupal_write_record('profile_values', $profile_value, array('fid', 'uid'));
286 }
287 else {
288 drupal_write_record('profile_values', $profile_value);
289 }
290 }
291
292 switch ($res) {
293 case SAVED_NEW:
294 $users_new++;
295 break;
296
297 case SAVED_UPDATED;
298 $users_updated++;
299 break;
300
301 default:
302 $users_failed++;
303 }
304 }
305
306 //delay
307 if ($i % $joomla_delay_row ==0 ) {sleep($joomla_delay_sec);}
308
309 //$percentage = $total;
310 //$message = "Imports users ...";
311
312 //$output = theme('progress_bar', $percentage, $message);
313 //$output .= '<p>Updating your site will take a few seconds.</p>';
314 // Note: do not output drupal_set_message()s until the summary page.
315 //print theme('maintenance_page', $output, FALSE);
316
317
318 return sprintf("Processed %d users (%d new, %d updated, %d errors)", $users_total, $users_new, $users_updated, $users_failed);
319 break;
320
321 case 'section':
322 $output = "";
323 $output .= "<h2>Import Joomla Sections and Categories</h2>";
324
325 $results_joomla_sec = db_query("SELECT * FROM %s.%ssections", $joomla_database, $joomla_prefix);
326
327 $i = 1;
328
329 //Joomla Sections to Drupal
330 while ( $data = db_fetch_object($results_joomla_sec) ) {
331 $i++;
332
333 //Get data
334 $sec_id = $data->id;
335 $sec_title = addslashes($data->title);
336 $sec_name = addslashes($data->name);
337
338 $results_check = db_query("SELECT COUNT(*) FROM {vocabulary} WHERE name='%s'", $sec_title);
339
340 $rec_status = 'Exist';
341 //Insert Sections
342 if (db_result($results_check) == 0) {
343 $rec_status = 'New';
344
345 db_query("INSERT INTO {vocabulary} (name,description,hierarchy,weight) values ('%s','%s',1,0)", $sec_title, $sec_name);
346 }
347
348 //Take Vocabulary ID
349 $vid = db_result(db_query("SELECT vid FROM {vocabulary} WHERE name='%s'", $sec_title));
350
351 //Retrieve and Insert categories
352 $results_cat = db_query("SELECT id,title,name,section FROM %s.%scategories WHERE section='%s'", $joomla_database, $joomla_prefix, $sec_id);
353
354 while ( $data_cat = db_fetch_object($results_cat) ) {
355 $cat_id = $data_cat->id;
356 $cat_title = addslashes($data_cat->title);
357 $cat_name = addslashes($data_cat->name);
358
359 //Check if cat exist on certain section
360 if (db_result(db_query("SELECT COUNT(*) FROM {term_data} WHERE name='%s' AND vid=%d", $cat_title, $vid)) == 0) {
361 db_query("INSERT INTO {term_data} (vid,name,description,weight) values (%d,'%s','%s',0)", $vid, $cat_title, $cat_name);
362
363 //Take Term ID
364 $tid = db_result(db_query("SELECT tid FROM {term_data} WHERE vid=%d AND name='%s'", $vid, $cat_title));
365
366 db_query("INSERT INTO {term_hierarchy} (tid,parent) values (%d,'0')", $tid);
367 }
368 }
369
370 if ($i % $joomla_delay_row ==0 ) {sleep($joomla_delay_sec);}
371 }
372 return "Total imported Sections: ". $i;
373 break;
374
375 case 'content':
376 $output = "";
377 $output .= "<h2>Import Joomla Contents</h2>";
378
379 $joomla_input_format = variable_get('joomla_input_format', '2');
380
381 $input_format = $joomla_input_format + 1;
382
383 $results_joomla = db_query("SELECT * FROM %s", $table_content);
384
385 $i = 1;
386 $images = array();
387
388 while ( $data_joomla = db_fetch_object($results_joomla) ) {
389 $i++;
390
391 //Check if content title already exists
392 $joomla_nid = $data_joomla->id;
393 $joomla_title = $data_joomla->title;
394 //Get Username
395 $joomla_uid = $data_joomla->created_by;
396 $results_user = db_query(" SELECT * FROM %s WHERE id = %d", $table_user, $joomla_uid);
397 $data_user = db_fetch_object($results_user);
398 $joomla_name = $data_user->username;
399 //Get Drupal uid
400 $results_get_uid = db_query("SELECT uid from {users} WHERE name= '%s'", $joomla_name);
401 $data_get_uid = db_fetch_object($results_get_uid);
402 $drupal_uid = $data_get_uid->uid;
403
404 $joomla_status = $data_joomla->state;
405 $joomla_created = strtotime($data_joomla->created);
406 $joomla_changed = strtotime($data_joomla->modified);
407 $joomla_comment = 0;
408
409 if ($data_joomla->sectionid==0) {$joomla_type = 'page';}
410 else {$joomla_type = 'story';};
411
412 $joomla_moderate = 0;
413 $joomla_sticky = 0;
414 $joomla_teaser = $data_joomla->introtext;
415 $joomla_body = $joomla_teaser ."<p></p>".$data_joomla->fulltext;
416 $joomla_body = str_replace("{mospagebreak}","",$joomla_body);
417
418 //images
419 if ($data_joomla->images) {
420 $joomla_teaser = replace_mos_image($data_joomla->images,$joomla_teaser);
421 $joomla_body = replace_mos_image($data_joomla->images,$joomla_body);
422 }
423
424 $joomla_teaser = replace_image_link($joomla_teaser);
425 $joomla_body = replace_image_link($joomla_body);
426
427 $joomla_title = addslashes($joomla_title);
428 $joomla_teaser = addslashes($joomla_teaser);
429 $joomla_body = addslashes($joomla_body);
430
431 //Check Frontpage
432 $results_check_fp = db_query("SELECT COUNT(*) FROM %s.%scontent_frontpage WHERE content_id='%d'", $joomla_database, $joomla_prefix, $joomla_nid);
433
434 if (db_result($results_check_fp) > 0) {
435 $joomla_promote = 1;
436 }
437 else {
438 $joomla_promote = 0;
439 }
440
441 //Check content/node exists
442 $rec_status = 'Ignore';
443
444 $results_check_content = db_query("SELECT COUNT(*) FROM {node} WHERE title='%s'", $joomla_title);
445
446 if (db_result($results_check_content) == 0) {
447 $rec_status = 'Insert';
448 //get last nid
449 $results_last_id = db_query("SELECT nid AS id from {node} ORDER BY nid DESC LIMIT 1");
450 $data_last_id = db_fetch_object($results_last_id);
451 $last_nid = $data_last_id->id +1;
452
453 db_query("INSERT INTO {node} (nid,vid,type,title,uid,status,created,changed,comment,promote,moderate,sticky) values (%d,%d,'%s','%s',%d,%d,%d,%d,%d,%d,%d,%d)", $last_nid, $last_nid, $joomla_type, $joomla_title, $drupal_uid, $joomla_status, $joomla_created, $joomla_changed, $joomla_comment, $joomla_promote, $joomla_moderate, $joomla_sticky);
454
455 //Intro and Body
456 db_query( " INSERT INTO {node_revisions} (nid,vid,uid,title,body,teaser,timestamp,format) values (%d,%d,%d,'%s','%s','%s',%d,%d)", $last_nid, $last_nid, $drupal_uid, $joomla_title, $joomla_body, $joomla_teaser, $joomla_changed, $input_format);
457 $rows[] = array(
458 $i++,
459 $joomla_nid."/".$last_nid, l(t("$joomla_title"),"node/$last_nid"), $rec_status
460 );
461 } else {
462 $rec_status = 'Ignore duplicate items.';
463 $results_last_id = db_query("SELECT nid AS id from {node} WHERE title='%s'", $joomla_title);
464 $data_last_id = db_fetch_object($results_last_id);
465 $last_nid = $data_last_id->id;
466
467 if ($joomla_update_duplicate) {
468 $rec_status = 'Update';
469
470 db_query("UPDATE {node} SET type='%s', uid=%d, status=%d, created=%d, changed=%d, promote=%d WHERE nid=%d", $joomla_type, $drupal_uid, $joomla_status, $joomla_created, $joomla_changed, $joomla_promote, $last_nid) ;
471
472 //Intro and Body
473 db_query("UPDATE {node_revisions} SET uid=%d, body='%s', teaser='%s',timestamp=%d, format=%d WHERE nid=%d", $drupal_uid, $joomla_body, $joomla_teaser, $joomla_changed, $input_format, $last_nid);
474 }
475 }
476 if ($i % $joomla_delay_row ==0 ) {sleep($joomla_delay_sec);}
477 }
478 return "Total imported Contents: $i. Action: $rec_status";
479 break;
480 }
481 }
482
483 function replace_mos_image($images_source,$text_source) {
484 $joomla_img_folder = variable_get('joomla_img_folder', '0');
485 $joomla_path = variable_get('joomla_path', '/home/your_username/public_html/joomla');
486
487 $images = array();
488 $images = explode("\n", $images_source);
489 $image_string = '{mosimage}';
490
491 $n=0;
492 $images_items =array();
493 while (!(strpos($text_source, $image_string) === false)) {
494
495 $images_items = explode("|",$images[$n]);
496
497 if (!file_exists(file_directory_path()."/".$joomla_img_folder)) {
498 mkdir(file_directory_path()."/".$joomla_img_folder);
499 }
500
501 if (dirname($images_items[0])) {
502 if (!file_exists(file_directory_path()."/".$joomla_img_folder."/".dirname($images_items[0]))) {
503 mkdir(file_directory_path()."/".$joomla_img_folder.'/'.dirname($images_items[0]));
504 }
505 }
506 copy($joomla_path."/images/stories/".$images_items[0],file_directory_path()."/$joomla_img_folder/".$images_items[0]);
507 $images_replace = '<img src="'.base_path().file_directory_path().'/'.$joomla_img_folder.'/'.$images_items[0].'"'
508 .' align="'.$images_items[1].'" title="'.$images_items[2].'" alt="'.$images_items[2].'"/>';
509 $text_source = substr_replace($text_source, $images_replace, strpos($text_source,$image_string), 10) ;
510 $n++;
511 }
512
513 return $text_source;
514 }
515
516 function replace_image_link($text_source) {
517 //Fixs image string: src="images/
518 $image_string = 'src="images/';
519 $images_replace = 'src="/files/images/';
520
521 $text_result = str_replace('src="images/', "$images_replace", $text_source);
522
523 return $text_result;
524 }
525
526 function joomla_form_alter(&$form, $form_state, $form_id) {
527 if ($form_id == 'user_login' || $form_id == 'user_login_block') {
528 if (isset($form_state['post']['name'])) {
529 $last_validator = array_pop($form['#validate']);
530 $form['#validate'][] = 'joomla_login_validate';
531 $form['#validate'][] = $last_validator;
532 }
533 }
534 }
535
536 function joomla_login_validate($form, &$form_state) {
537 joomla_authenticate($form_state['values']);
538 }
539
540 function joomla_authenticate($form_values = array()) {
541 global $user;
542
543 if (!empty($user->uid)) {
544 // User has already sucessfully authenticated
545 return;
546 }
547
548 if (form_get_errors() || empty($form_values['name']) || empty($form_values['pass'])) {
549 return;
550 }
551
552 $account = user_load(array('name' => $form_values['name'], 'status' => 1));
553
554 // The user doesn't exist
555 if (!$account) {
556 return;
557 }
558
559 // See if the user has a password record from Joomla import
560 $joomla_user = db_fetch_object(db_query('SELECT * FROM {joomla_users} WHERE uid = %d', $account->uid));
561 if (!$joomla_user) {
562 return;
563 }
564
565 /**
566 * If the password doesn't contain a colon, it is an unsalted password.
567 * It will have been inserted into the drupal users table during the
568 * import, and to get here the Drupal login must have already failed
569 * against it, so nothing left to do
570 */
571 list($password, $salt) = explode(':', $joomla_user->password, 2);
572 if(!$salt) {
573 return;
574 }
575
576 // Check the salt + supplied password against the md5sum
577 if (md5($form_values['pass'] . $salt) == $password) {
578 $user = $account;
579 watchdog('joomla', 'Converting password for user @name (Joomla id @juid)', array('@name' => $user->name, '@juid' => $joomla_user->juid));
580
581 // Update the users Drupal password
582 user_save($user, array('pass' => $form_values['pass']));
583
584 $joomla_user->converted = 1;
585 drupal_write_record('joomla_users', $joomla_user, array('uid'));
586
587 user_authenticate_finalize($form_values);
588 return $user;
589 }
590 }

  ViewVC Help
Powered by ViewVC 1.1.2