[LON-CAPA-cvs] cvs: modules /gerd/loncapa_lernmodule README enrolldump.php /gerd/loncapa_lernmodule/loncapa studip.pm /gerd/loncapa_lernmodule/studip/public/assets/images/logos lon-capa.gif /gerd/loncapa_lernmodule/studip/templates/elearning loncapa_connected_link.php loncapa_connected_link_edit.php
www
www at source.lon-capa.org
Thu Aug 30 04:38:47 EDT 2012
www Thu Aug 30 08:38:47 2012 EDT
Added files:
/modules/gerd/loncapa_lernmodule README enrolldump.php
/modules/gerd/loncapa_lernmodule/loncapa studip.pm
/modules/gerd/loncapa_lernmodule/studip/public/assets/images/logos
lon-capa.gif
/modules/gerd/loncapa_lernmodule/studip/templates/elearning
loncapa_connected_link.php
loncapa_connected_link_edit.php
Log:
StudIP integration - work in progress. Files from Wibke Boerger
-------------- next part --------------
Index: modules/gerd/loncapa_lernmodule/enrolldump.php
+++ modules/gerd/loncapa_lernmodule/enrolldump.php
<?php
require '../lib/bootstrap.php';
if(!$_GET['course_id'] || !$_GET['inst_code']){
exit();
}
$course_id = preg_replace('/\W/', '', $_GET['course_id']);
$inst_code = preg_replace('/\W/', '', $_GET['inst_code']);
$dbh = DBManager::get();
$stmt = "select username, vorname, nachname, email from object_contentmodules left join seminar_user on (object_id=seminar_id) left join auth_user_md5 using(user_id) where module_id=? and seminar_user.status='autor'";
$sth = $dbh->prepare($stmt);
$sth->execute(array($course_id));
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE text>
<students>
";
while($row = $sth->fetch(PDO::FETCH_ASSOC)){
$autharg = '';
$authtype = 'internal';
$xml .= "<student username=\"{$row['username']}\">
<autharg>$autharg</autharg>
<authtype>$authtype</authtype>
<email>{$row['email']}</email>
<enddate></enddate>
<firstname>{$row['vorname']}</firstname>
<generation></generation>
<groupID></groupID>
<lastname>{$row['nachname']}</lastname>
<middlename></middlename>
<startdate></startdate>
<studentID></studentID>
</student>\n";
}
$xml .= "</students>";
header('Content-disposition: attachment; filename='.$course_id.'_'.$inst_code.'_classlist.xml');
print $xml;
exit();
?>
Index: modules/gerd/loncapa_lernmodule/loncapa/studip.pm
+++ modules/gerd/loncapa_lernmodule/loncapa/studip.pm
# The LearningOnline Network
#
# Landing point for incoming StudIP requests
#
# $Id: studip.pm,v 1.1 2012/08/30 08:38:46 www Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
#
=pod
=head1 NAME
Apache::studip: incoming link from studip
=head1 SYNOPSIS
This is part of the LearningOnline Network with CAPA project
described at http://www.lon-capa.org.
=head1 OVERVIEW
Incoming from StudIP
=cut
package Apache::studip;
use strict;
use Apache::Constants qw(:common :http);
use Apache::lonacc;
use Apache::lonnet;
use Apache::loncommon;
use Apache::lonlocal;
use LONCAPA;
use LWP::UserAgent;
use RPC::XML::ParserFactory;
# Config parameters
# url of studip webservice
my $studip_url = 'http://192.168.122.3/studip/xmlrpc.php';
# password for studip webservice
my $studip_pwd = 'qip(hF2tvYcU0ehd';
# list of remote ips which get access to course list
my @studip_ips = ('192.168.122.3', '192.168.122.1');
my $ua = LWP::UserAgent->new;
my $parser = RPC::XML::ParserFactory->new();
my $domain = &Apache::lonnet::default_login_domain();
# url patterns of valid routes
my %routes = (
'^courses$' => 'courses',
'^course\/(?<course_id>[a-zA-Z0-9_]+)$' => 'course',
'^enter\/(?<course_id>[a-zA-Z0-9_]+)$' => 'enter'
);
# registry of route callbacks
my %request_handlers;
# wrapper for lonnet's courseiddump
sub get_courseiddump{
my ($domain, $courseid, $owner, $desc) = @_;
my $domfilter = $domain;
my $descfilter = $desc ? $desc : '.';
my $sincefilter = 1;
my $instcodefilter = '.';
my $ownerfilter = $owner ? $owner : '.';
my $coursefilter = $courseid ? $courseid : '.';
my $hostidflag = undef;
my $hostidref = undef;
my $typefilter = 'Course';
my %courses = &Apache::lonnet::courseiddump($domfilter,$descfilter,$sincefilter,$instcodefilter,$ownerfilter,$coursefilter,$hostidflag,$hostidref,$typefilter);
return %courses;
}
# get list of courses in this domain, optional parameters owner and search (description)
sub get_courses{
my ($r, $params, $query_string) = @_;
if(!allowed_ip($ENV{'REMOTE_ADDR'})){
return &error_msg($r, FORBIDDEN);
}
if($query_string){
&Apache::loncommon::get_unprocessed_cgi($query_string, ['owner', 'search']);
}
my %courses = &get_courseiddump($domain, undef, $env{'form.owner'}, $env{'form.search'});
my $xml = &course_wrap(%courses);
return &xml_response($r, $xml);
}
$request_handlers{'courses'} = \&get_courses;
# get one course, specified by course_id
sub get_course{
my ($r, $params, $query_string) = @_;
if(!&allowed_ip($ENV{'REMOTE_ADDR'})){
return &error_msg($r, FORBIDDEN);
}
my ($dom, $id) = split(/_/, $$params{'course_id'});
my %courses = &get_courseiddump($dom, $id);
if(!%courses){
return &error_msg($r,NOT_FOUND);
}
my $xml = &course_wrap(%courses);
return &xml_response($r, $xml);
}
$request_handlers{'course'} = \&get_course;
# authenticate user and forward him to course contents
# only for users and courses in local domain
sub enter_course{
my ($r, $params, $query_string) = @_;
if($query_string){
&Apache::loncommon::get_unprocessed_cgi($query_string, ['token']);
}
if(!$env{'form.token'}){
return &error_msg($r, HTTP_UNAUTHORIZED);
}
# verify stuidp session
my($error, $returned) = &make_studip_call('get_session_username', $env{'form.token'});
if($error){
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
$r->print($error);
return OK;
}
my $user = $returned->value;
if(!$user){
&Apache::lonauth::failed($r, 'Couldn\'t verifiy token.', undef);
return OK;
#return &error_msg($r, HTTP_UNAUTHORIZED);
}
$user = &LONCAPA::clean_username($user);
my %form = (
'uname' => $user,
'udom' => $domain
);
# only check against own domain
my $uhome = &Apache::lonnet::homeserver($user, $domain);
if($uhome eq 'no_host'){
&Apache::lonauth::failed($r, "The user $user doesn\'t exist in this domain.", \%form);
return OK;
#return &error_msg($r, HTTP_UNAUTHORIZED);
}
# user is authenticated from here on
my ($cdom, $cid) = split(/_/, $$params{'course_id'});
if($cdom eq $domain){
my %roles = &Apache::lonnet::get_my_roles($user, $domain, 'userroles');
my $matched_role = undef;
for my $key (keys %roles){
my($rcid, $rcdom, $role) = split(':', $key);
if($rcid eq $cid && $rcdom eq $cdom){
$matched_role = $role.'./'.$rcdom.'/'.$rcid;
last;
}
}
if($matched_role){
$form{'role'} = $matched_role;
$form{'symb'} = '/adm/navmaps';
}
}
my $next_url = '/adm/roles';
&Apache::lonauth::success($r, $user, $domain, $uhome, $next_url, undef, \%form);
return OK;
}
$request_handlers{'enter'} = \&enter_course;
# wrap %courses hash into xml
sub course_wrap{
my %courses = @_;
my $xml = "<?xml version=\"1.0\"?>\n";
$xml .= "<courses>\n";
for my $id(keys %courses){
$xml .= "<course>\n";
$xml .= "<id>$id</id>\n";
for my $p(keys %{$courses{$id}}){
$xml .= "<$p>$courses{$id}{$p}</$p>\n";
}
$xml .= "</course>";
}
$xml .= "</courses>\n";
}
# XML response for requests for course lists
sub xml_response{
my($r, $data) = @_;
&Apache::loncommon::content_type($r,'application/xml');
$r->send_http_header;
$r->print($data);
return OK;
}
sub html_wrap{
my($title, $msg) = @_;
return <<EOF;
<html>
<head><title>$title</title></head>
<body>
<h1>$title</h1>
<p>$msg</p>
</body>
</html>
EOF
}
sub error_msg{
my($r, $status_code) = @_;
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
return $status_code;
}
sub not_found{
my $r = shift;
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
$r->print(html_wrap('Not Found', 'The requested URL was not found on this server.'));
return NOT_FOUND;
}
sub index_page{
my $r = shift;
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
$r->print(html_wrap('', '...this is not the page you\'re looking for.'));
return OK;
}
# check if $ip is in the list of allowed server ips
sub allowed_ip{
my $ip = shift;
my $pattern = '^'.$ip.'$';
my $c = grep(/$pattern/, @studip_ips);
if($c == 1){
return 1;
}
return 0;
}
# dispatching of routes
# valid routes (as defined above) are:
# /courses - to get a list of all courses in the domain
# /courses?owner=xy&search=title - to filter by owner and/or description
# /enter/{course_id}?token={token} - authenticate against token and enter the course with the id course_id
#
sub handler{
my $r = shift;
my $path_info = $ENV{'PATH_INFO'};
my $query_string = $ENV{'QUERY_STRING'};
if(!$path_info || $path_info eq '/'){
return &index_page($r);
}
$path_info =~ s/^\///;
$path_info =~ s/\/$//;
my $handler = undef;
my %params = undef;
for my $pattern(keys %routes){
my $endpoint = $routes{$pattern};
if(($path_info =~ /$pattern/) && ($request_handlers{$endpoint})){
$handler = $request_handlers{$endpoint};
%params = %+;
last;
}
}
if($handler){
return &$handler($r, \%params, $query_string);
}
return &error_msg($r, NOT_FOUND);
}
# XML-RPC request to studip
sub make_studip_call{
my ($cmd, @args) = @_;
my $xml = xmlrpc_wrap($cmd, $studip_pwd, @args);
my $headers = HTTP::Headers->new() ;
my $request = HTTP::Request->new('POST', $studip_url, $headers);
$request->content($xml);
$ua->timeout(4);
my $response = $ua->request($request);
my $returned;
my $error = '';
if($response->is_success()){
my $rpcxml_response = $parser->parse($response->content);
if(!$rpcxml_response->is_fault){
$returned = $rpcxml_response->value;
}
else{
$error = "ERROR: ".$rpcxml_response->value;
}
}
else{
$error = "ERROR: ".$response->status_line;
}
return ($error, $returned);
}
sub xmlrpc_wrap{
my ($method, @params) = @_;
my $paramstr = '';
for(@params){
$paramstr .= '<param><value><string>'.$_.'</string></value></param>'."\n";
}
return <<EOF;
<?xml version="1.0"?>
<methodCall>
<methodName>$method</methodName>
<params>
$paramstr
</params>
</methodCall>
EOF
}
1;
Index: modules/gerd/loncapa_lernmodule/studip/templates/elearning/loncapa_connected_link.php
+++ modules/gerd/loncapa_lernmodule/studip/templates/elearning/loncapa_connected_link.php
<a href="<?= htmlspecialchars($url) ?>" target="_blank">
<?= makeButton('starten', 'img')?>
</a>
Index: modules/gerd/loncapa_lernmodule/studip/templates/elearning/loncapa_connected_link_edit.php
+++ modules/gerd/loncapa_lernmodule/studip/templates/elearning/loncapa_connected_link_edit.php
<form method="post" action="<?= URLHelper::getLink() ?>">
<input type="hidden" name="view" value="<?= $view ?>">
<input type="hidden" name="search_key" value="<?= $search_key ?>">
<input type="hidden" name="cms_select" value="<?= $cms_select ?>">
<input type="hidden" name="module_type" value="loncapa">
<input type="hidden" name="module_id" value="<?= $current_module ?>">
<input type="hidden" name="module_system_type" value="<?= $cms_type ?>">
<? if ($connected) : ?>
<?= makeButton('entfernen', 'input', false, 'remove') ?>
<? else : ?>
<?= makeButton('hinzufuegen', 'input', false, 'add') ?>
<? endif ?>
</form>
More information about the LON-CAPA-cvs
mailing list