cvsimport fixups -- cvshead had strayed from upstream

This commit is contained in:
Martin Langhoff 2007-01-04 13:15:04 +13:00
parent b8806cccdf
commit f3f7610c90
171 changed files with 1548 additions and 25184 deletions

View File

@ -1,185 +0,0 @@
<?php // $Id$
// config.php - allows admin to edit all configuration variables
require_once('../config.php');
$focus = '';
if ($site = get_site()) { // If false then this is a new installation
require_login();
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM, SITEID));
}
/// This is to overcome the "insecure forms paradox"
if (isset($secureforms) and $secureforms == 0) {
$match = 'nomatch';
} else {
$match = '';
}
/// If data submitted, then process and store.
if ($config = data_submitted($match)) {
if (!empty($USER->id)) { // Additional identity check
if (!confirm_sesskey()) {
error(get_string('confirmsesskeybad', 'error'));
}
}
validate_form($config, $err);
if (count($err) == 0) {
foreach ($config as $name => $value) {
if ($name == "sessioncookie") {
$value = eregi_replace("[^a-zA-Z0-9_]", "", $value);
}
if ($name == "defaultallowedmodules") {
$value = implode(',',$value);
}
if ($name == 'hiddenuserfields') {
if (in_array('none', $value)) {
$value = '';
} else {
$value = implode(',',$value);
}
}
if ($name == "locale") {
$value = trim($value);
}
$conf = new object();
$conf->name = $name;
$conf->value = $value;
if ($current = get_record('config', 'name', $name)) {
$conf->id = $current->id;
if (! update_record('config', $conf)) {
error("Error: Could not update $name to $value");
}
} else {
if (! insert_record('config', $conf)) {
error("Error: could not add new variable $name !");
}
}
}
redirect('index.php');
exit;
} else {
foreach ($err as $key => $value) {
$focus = "form.$key";
}
}
}
/// Otherwise fill and print the form.
if (empty($config)) {
$config = $CFG;
}
$sesskey = !empty($USER->id) ? $USER->sesskey : '';
$stradmin = get_string('administration');
$strconfiguration = get_string('configuration');
$strconfigvariables = get_string('configvariables', 'admin');
if ($site) {
print_header("$site->shortname: $strconfigvariables", $site->fullname,
"<a href=\"index.php\">$stradmin</a> -> ".
"<a href=\"configure.php\">$strconfiguration</a> -> $strconfigvariables", $focus);
print_heading($strconfigvariables);
} else {
print_header();
print_heading($strconfigvariables);
print_simple_box(get_string('configintro', 'admin'), 'center', "50%");
echo '<br />';
}
/// Get all the configuration fields and helptext
require('configvars.php');
/// Cycle through the sections to get the sectionnames
$linktext = '';
foreach($configvars as $sectionname=>$section) {
if ($linktext !== '') {
$linktext .= ' | ';
}
$linktext .= '<a href="#configsection'.$sectionname.'">'.get_string('configsection'.$sectionname, 'admin').'</a>';
}
echo "<center>$linktext</center>\n";
echo '<form method="post" action="config.php" name="form">';
echo '<center><input type="submit" value="'.get_string('savechanges').'" /></center>';
/// Cycle through each section of the configuration
foreach ($configvars as $sectionname=>$section) {
print_heading('<a name="configsection'.$sectionname.'"></a>'.get_string('configsection'.$sectionname, 'admin'));
$table = NULL;
$table->data = array();
foreach ($section as $configvariable=>$configobject) {
$table->data[] = array ( $configvariable.': ',
$configobject->field
);
if ($configobject->display_warning()) {
$table->data[] = array ( '&nbsp;',
'<span class="configwarning">'.$configobject->warning.'</span>'
);
}
$table->data[] = array ( '&nbsp;',
'<span class="confighelp">'.$configobject->help.'</span>'
);
$table->align = array ('right', 'left');
}
print_table($table);
}
echo '<center>';
echo '<input type="hidden" name="sesskey" value="'.$sesskey.'" />';
echo '<input type="submit" value="'.get_string('savechanges').'" />';
echo '</center>';
echo '</form>';
/// Lock some options
$httpsurl = str_replace('http://', 'https://', $CFG->wwwroot);
if ($httpsurl != $CFG->wwwroot) {
if (ini_get('allow_url_fopen')) {
if ((($fh = @fopen($httpsurl, 'r')) == false) and ($config->loginhttps == 0)) {
echo '<script type="text/javascript">'."\n";
echo '<!--'."\n";
echo "eval('document.form.loginhttps.disabled=true');\n";
echo '-->'."\n";
echo '</script>'."\n";
}
}
}
if ($site) {
print_footer();
}
exit;
/// Functions /////////////////////////////////////////////////////////////////
function validate_form(&$form, &$err) {
// Currently no checks are needed ...
return true;
}
?>

View File

@ -1,660 +0,0 @@
<?php // $Id$
// Shane Elliott
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
/// Add new sitewide configuration variables to this file.
/// $configvars is parsed by config.php
/// It is an array of arrays of objects
/// $configvars[sectionname][configvariablename] = configvar object
$configvars = array();
/// no, yes strings and menu options are used in a number of places
/// so we define them here to save time on repeatedly calling
/// get_string()
$stryes = get_string('yes');
$strno = get_string('no');
$noyesoptions[0] = $strno;
$noyesoptions[1] = $stryes;
/// A class to hold the configurable information
/// $field - the html code for the form field
/// $help - help text for the field
/// $warning - optional warning text to be displayed
/// method display_warning() - a generic function that can be used in an extended class
/// e.g. enablerssfeeds
class configvar {
var $field;
var $help;
var $warning;
function configvar($help, $field, $warning='') {
$this->help = $help;
$this->field = $field;
$this->warning = $warning;
}
function display_warning() {
return false;
}
}
////////////////////////////////////////////////////////////////////
/// Miscellaneous config variables
////////////////////////////////////////////////////////////////////
$misc = array();
/// maxeditingtime
unset($options);
$options[3600] = get_string('numminutes', '', 60);
$options[2700] = get_string('numminutes', '', 45);
$options[1800] = get_string('numminutes', '', 30);
$options[900] = get_string('numminutes', '', 15);
$options[300] = get_string('numminutes', '', 5);
$options[60] = get_string('numminutes', '', 1);
$misc['maxeditingtime'] = new configvar (get_string('configmaxeditingtime', 'admin'),
choose_from_menu ($options, 'maxeditingtime', $config->maxeditingtime, '', '', '', true) );
/// debug
unset($options);
$options[5] = $strno;
$options[15] = $stryes;
$misc['debug'] = new configvar (get_string('configdebug', 'admin'),
choose_from_menu ($options, 'debug', $config->debug, '', '', '', true) );
$misc['perfdebug'] = new configvar (get_string('configperfdebug', 'admin'),
choose_from_menu ($options, 'perfdebug', $config->perfdebug, '', '', '', true) );
/// enablerssfeeds
class configvarrss extends configvar {
function display_warning() {
return (!function_exists('utf8_encode'));
}
}
$misc['enablerssfeeds'] = new configvarrss (get_string('configenablerssfeeds', 'admin'),
choose_from_menu ($noyesoptions, 'enablerssfeeds', $config->enablerssfeeds, '', '', '', true),
'<font color="red"> You need to add XML support to your PHP installation.</font>' );
$misc['mymoodleredirect'] = new configvar (get_string('configmymoodleredirect','admin'),
choose_from_menu($noyesoptions,'mymoodleredirect',$config->mymoodleredirect,'','','',true));
unset($options);
$options[5] = get_string('worldblogs','blog');
$options[4] = get_string('siteblogs','blog');
$options[3] = get_string('courseblogs','blog');
$options[2] = get_string('groupblogs','blog');
$options[1] = get_string('personalblogs','blog');
$options[0] = get_string('disableblogs','blog');
$misc['bloglevel'] = new configvar (get_string('configbloglevel', 'admin'),
choose_from_menu ($options, 'bloglevel', $config->bloglevel,'','','',true));
////////////////////////////////////////////////////////////////////
/// OPERATING SYSTEM config variables
////////////////////////////////////////////////////////////////////
$operatingsystem = array();
/// gdversion
unset($options);
$options[0] = get_string('gdnot');
$options[1] = get_string('gd1');
$options[2] = get_string('gd2');
$installed = check_gd_version();
$operatingsystem['gdversion'] = new configvar (get_string('configgdversion', 'admin'),
choose_from_menu ($options, 'gdversion', $installed, '', '', '', true) );
/// dbsessions
$operatingsystem['dbsessions'] = new configvar (get_string('configdbsessions', 'admin'),
choose_from_menu ($noyesoptions, 'dbsessions', $config->dbsessions, '', '', '', true) );
/// sessiontimeout
unset($options);
$options[14400] = get_string('numhours', '', 4);
$options[10800] = get_string('numhours', '', 3);
$options[7200] = get_string('numhours', '', 2);
$options[5400] = get_string('numhours', '', '1.5');
$options[3600] = get_string('numminutes', '', 60);
$options[2700] = get_string('numminutes', '', 45);
$options[1800] = get_string('numminutes', '', 30);
$options[900] = get_string('numminutes', '', 15);
$options[300] = get_string('numminutes', '', 5);
$operatingsystem['sessiontimeout'] = new configvar (get_string('configsessiontimeout', 'admin'),
choose_from_menu ($options, 'sessiontimeout', $config->sessiontimeout, '', '', '', true) );
/// sessioncookie
$operatingsystem['sessioncookie'] = new configvar (get_string('configsessioncookie', 'admin'),
'<input name="sessioncookie" type="text" size="10" value="'.s($config->sessioncookie).'" alt="sessioncookie" />' );
$operatingsystem['sessioncookiepath'] = new configvar (get_string('configsessioncookiepath', 'admin'),
'<input name="sessioncookiepath" type="text" size="10" value="'.s($config->sessioncookiepath).'" alt="sessioncookiepath" />' );
/// zip
$operatingsystem['zip'] = new configvar (get_string('configzip', 'admin'),
'<input name="zip" type="text" size="30" value="'.s($config->zip).'" alt="zip" />' );
/// unzip
$operatingsystem['unzip'] = new configvar (get_string('configunzip', 'admin'),
'<input name="unzip" type="text" size="30" value="'.s($config->unzip).'" alt="unzip" />' );
$operatingsystem['pathtodu'] = new configvar(get_string('configpathtodu', 'admin'),
'<input name="pathtodu" type="text" size="30" value="'.s($config->pathtodu).'" alt="pathtodu" />');
/// slasharguments
unset($options);
$options[0] = "file.php?file=/1/pic.jpg";
$options[1] = "file.php/1/pic.jpg";
$operatingsystem['slasharguments'] = new configvar (get_string('configslasharguments', 'admin'),
choose_from_menu ($options, 'slasharguments', $config->slasharguments, '', '', '', true) );
/// proxyhost
$operatingsystem['proxyhost'] = new configvar (get_string('configproxyhost', 'admin'),
'<input name="proxyhost" type="text" size="30" value="'.s($config->proxyhost).'" alt="proxyhost" />' );
/// proxyport
$operatingsystem['proxyport'] = new configvar ('',
'<input name="proxyport" type="text" size="5" value="'.s($config->proxyport).'" alt="proxyport" />' );
////////////////////////////////////////////////////////////////////
/// PERMISSIONS config variables
////////////////////////////////////////////////////////////////////
$permissions = array();
/// teacherassignteachers
$permissions['teacherassignteachers'] = new configvar (get_string('configteacherassignteachers', 'admin'),
choose_from_menu ($noyesoptions, 'teacherassignteachers', $config->teacherassignteachers, '', '', '', true) );
/// allowunenroll
$permissions['allowunenroll'] = new configvar (get_string('configallowunenroll', 'admin'),
choose_from_menu ($noyesoptions, 'allowunenroll', $config->allowunenroll, '', '', '', true) );
/// allusersaresitestudents
$permissions['allusersaresitestudents'] = new configvar (get_string('configallusersaresitestudents', 'admin'),
choose_from_menu ($noyesoptions, 'allusersaresitestudents', $config->allusersaresitestudents, '', '', '', true) );
/// showsiteparticipantslist
unset($options);
$options[0] = get_string('siteteachers');
$options[1] = get_string('allteachers');
$options[2] = get_string('studentsandteachers');
$permissions['showsiteparticipantslist'] = new configvar (get_string('configshowsiteparticipantslist', 'admin'),
choose_from_menu ($options, 'showsiteparticipantslist', $config->showsiteparticipantslist, '', '', '', true) );
/// forcelogin
$permissions['forcelogin'] = new configvar (get_string('configforcelogin', 'admin'),
choose_from_menu ($noyesoptions, 'forcelogin', $config->forcelogin, '', '', '', true) );
/// forceloginforprofiles
$permissions['forceloginforprofiles'] = new configvar (get_string('configforceloginforprofiles', 'admin'),
choose_from_menu ($noyesoptions, 'forceloginforprofiles', $config->forceloginforprofiles, '', '', '', true) );
/// opentogoogle
$permissions['opentogoogle'] = new configvar (get_string('configopentogoogle', 'admin'),
choose_from_menu ($noyesoptions, 'opentogoogle', $config->opentogoogle, '', '', '', true) );
/// maxbytes
$options = get_max_upload_sizes();
$permissions['maxbytes'] = new configvar (get_string('configmaxbytes', 'admin'),
choose_from_menu ($options, 'maxbytes', $config->maxbytes, '', '', 0, true) );
/// messaging
$permissions['messaging'] = new configvar (get_string('configmessaging', 'admin'),
choose_from_menu ($noyesoptions, 'messaging', $config->messaging, '', '', '', true) );
/// allowobjectembed
$permissions['allowobjectembed'] = new configvar (get_string('configallowobjectembed', 'admin'),
choose_from_menu ($noyesoptions, 'allowobjectembed', $config->allowobjectembed, '', '', '', true) );
/// enabletrusttext
$permissions['enabletrusttext'] = new configvar (get_string('configenabletrusttext', 'admin'),
choose_from_menu ($noyesoptions, 'enabletrusttext', $config->enabletrusttext, '', '', '', true) );
unset($options);
$options['none'] = 'No courses';
$options['all'] = 'All courses';
$options['requested'] = 'Requested courses';
$permissions['restrictmodulesfor'] = new configvar (get_string('configrestrictmodulesfor','admin'),
' <script language="JavaScript">
function togglemodules(index) {
if (index == 0) {
document.getElementById(\'allowedmodules\').disabled=true;
}
else {
document.getElementById(\'allowedmodules\').disabled=false;
}
}
</script>'.
choose_from_menu($options,'restrictmodulesfor',$config->restrictmodulesfor,'','togglemodules(this.selectedIndex);','',true) );
$permissions['restrictbydefault'] = new configvar (get_string('configrestrictbydefault','admin'),
choose_from_menu($noyesoptions, 'restrictbydefault',$config->restrictbydefault,'','','',true) );
$allowstr = '<select name="defaultallowedmodules[]" id="allowedmodules" multiple="multiple" size="10"'.((empty($config->restrictmodulesfor)) ? "disabled=\"disabled\"" : "").'>';
$allowedmodules = array();
if (!empty($config->defaultallowedmodules)) {
$allowedmodules = explode(',',$config->defaultallowedmodules);
}
// On a fresh install of Moodle, this could be empty; prevent a warning on the following loop.
if (!$mods = get_records("modules")) {
$mods = array();
}
$s = "selected=\"selected\"";
$allowstr .= '<option value="0" '.((empty($allowedmodules)) ? $s : '').'>'.get_string('allownone').'</option>'."\n";
foreach ($mods as $mod) {
$selected = "";
if (in_array($mod->id,$allowedmodules))
$selected = $s;
$allowstr .= '<option '.$selected.' value="'.$mod->id.'">'.$mod->name.'</option>'."\n";
}
$allowstr .= '</select>';
$permissions['defaultallowedmodules'] = new configvar (get_string('configdefaultallowedmodules','admin'),$allowstr);
/// course requests
$reqcourse['enablecourserequests'] = new configvar (get_string('configenablecourserequests', 'admin'),
choose_from_menu ($noyesoptions,'enablecourserequests',$config->enablecourserequests,'','','',true) );
/// default category for course requests
require_once($CFG->dirroot.'/course/lib.php');
$reqcourse['defaultrequestedcategory'] = new configvar (get_string('configdefaultrequestedcategory', 'admin'),
choose_from_menu (make_categories_options(), 'defaultrequestedcategory',$config->defaultrequestedcategory,'','','',true) );
$reqcourse['requestedteachername'] = new configvar (get_string('configrequestedteachername','admin'),
'<input type="text" name="requestedteachername" size="20" maxlength="100" value="'.s($config->requestedteachername).'" />');
$reqcourse['requestedteachersname'] = new configvar (get_string('configrequestedteachersname','admin'),
'<input type="text" name="requestedteachersname" size="20" maxlength="100" value="'.s($config->requestedteachersname).'" />');
$reqcourse['requestedstudentname'] = new configvar (get_string('configrequestedstudentname','admin'),
'<input type="text" name="requestedstudentname" size="20" maxlength="100" value="'.s($config->requestedstudentname).'" />');
$reqcourse['requestedstudentsname'] = new configvar (get_string('configrequestedstudentsname','admin'),
'<input type="text" name="requestedstudentsname" size="20" maxlength="100" value="'.s($config->requestedstudentsname).'" />');
////////////////////////////////////////////////////////////////////
/// INTERFACE config variables
////////////////////////////////////////////////////////////////////
$interface = array();
/// language settings
$interface['lang'] = new configvar ( get_string('configlang', 'admin'),
choose_from_menu(get_list_of_languages(), 'lang', $config->lang, '', '', '', true) );
/// language menu
$interface['langmenu'] = new configvar ( get_string('configlangmenu', 'admin'),
choose_from_menu($noyesoptions, 'langmenu', $config->langmenu, '', '', '', true) );
/// language list
$interface['langlist'] = new configvar ( get_string('configlanglist', 'admin'),
'<input name="langlist" type="text" size="60" value="'.s($config->langlist).'" alt="langlist" />' );
/// language menu
$interface['langcache'] = new configvar ( get_string('configlangcache', 'admin'),
choose_from_menu($noyesoptions, 'langcache', $config->langcache, '', '', '', true) );
/// locale
$interface['locale'] = new configvar ( get_string('configlocale', 'admin'),
'<input name="locale" type="text" size="15" value="'.s($config->locale).'" alt="locale" />' );
/// docroot
$interface['docroot'] = new configvar ( get_string('configdocroot', 'admin'),
'<input name="docroot" type="text" size="60" value="'.s($config->docroot).'" alt="docroot" />' );
/// doctonewwindow
$interface['doctonewwindow'] = new configvar ( get_string('configdoctonewwindow', 'admin'),
choose_from_menu($noyesoptions, 'doctonewwindow', $config->doctonewwindow, '', '', '', true) );
/// timezone
$interface['timezone'] = new configvar ( get_string('configtimezone', 'admin'),
choose_from_menu (get_list_of_timezones(), 'timezone', $config->timezone, get_string('serverlocaltime'), '', '99', true ) );
/// country
$interface['country'] = new configvar ( get_string('configcountry', 'admin'),
choose_from_menu (get_list_of_countries(), 'country', $config->country, get_string('selectacountry'), '', 0, true) );
/// framename
if (empty($config->framename)) {
$config->framename = "_top";
}
$interface['framename'] = new configvar (get_string('configframename', 'admin'),
'<input name="framename" type="text" size="15" value="'.s($config->framename).'" alt="framename" />' );
/// language list
$interface['themelist'] = new configvar ( get_string('configthemelist', 'admin'),
'<input name="themelist" type="text" size="60" value="'.s($config->themelist).'" alt="themelist" />' );
/// user themes
$interface['allowuserthemes'] = new configvar (get_string('configallowuserthemes', 'admin'),
choose_from_menu ($noyesoptions, 'allowuserthemes', $config->allowuserthemes, '', '', '', true) );
/// course themes
$interface['allowcoursethemes'] = new configvar (get_string('configallowcoursethemes', 'admin'),
choose_from_menu ($noyesoptions, 'allowcoursethemes', $config->allowcoursethemes, '', '', '', true) );
/// allowuserblockhiding
$interface['allowuserblockhiding'] = new configvar (get_string('configallowuserblockhiding', 'admin'),
choose_from_menu ($noyesoptions, 'allowuserblockhiding', $config->allowuserblockhiding, '', '', '', true) );
/// showblocksonmodpages
$interface['showblocksonmodpages'] = new configvar (get_string('configshowblocksonmodpages', 'admin'),
choose_from_menu ($noyesoptions, 'showblocksonmodpages', $config->showblocksonmodpages, '', '', '', true) );
/// tabselectedtofront
$interface['tabselectedtofront'] = new configvar (get_string('tabselectedtofront', 'admin'),
choose_from_menu ($noyesoptions, 'tabselectedtofront', $config->tabselectedtofront, '', '', '', true) );
////////////////////////////////////////////////////////////////////
/// USER config variables
////////////////////////////////////////////////////////////////////
$user = array();
/// sitepolicy
$user['sitepolicy'] = new configvar (get_string('configsitepolicy', 'admin'),
'<input type="text" name="sitepolicy" size="60" value="'.$config->sitepolicy.'" alt="sitepolicy" />' );
/// fullnamedisplay
unset($options);
$options['language'] = get_string('language');
$options['firstname lastname'] = get_string('firstname') . ' + ' . get_string('lastname');
$options['lastname firstname'] = get_string('lastname') . ' + ' . get_string('firstname');
$options['firstname'] = get_string('firstname');
$user['fullnamedisplay'] = new configvar (get_string('configfullnamedisplay', 'admin'),
choose_from_menu ($options, 'fullnamedisplay', $config->fullnamedisplay, '', '', '', true) );
/// extendedusernamechars
$user['extendedusernamechars'] = new configvar (get_string('configextendedusernamechars', 'admin'),
choose_from_menu ($noyesoptions, 'extendedusernamechars', $config->extendedusernamechars, '', '', '', true) );
/// autologinguests
$user['autologinguests'] = new configvar (get_string('configautologinguests', 'admin'),
choose_from_menu ($noyesoptions, 'autologinguests', $config->autologinguests, '', '', '', true) );
/// hiddenuserfields
$fields = array('none', 'description', 'city', 'country', 'webpage', 'icqnumber', 'skypeid', 'yahooid', 'aimid', 'msnid', 'lastaccess');
if (empty($config->hiddenuserfields)) {
$config->hiddenuserfields = 'none';
}
$configfields = array_flip(explode(',', $config->hiddenuserfields));
$fieldoptions = '';
foreach ($fields as $value) {
$fieldoptions .= '<option value="'.$value.'"';
if (isset($configfields[$value])) {
$fieldoptions .= ' selected="selected"';
}
$fieldoptions .= '>'.get_string($value).'</option>';
}
$user['hiddenuserfields'] = new configvar (get_string('confighiddenuserfields', 'admin'),
'<select id="menuhiddenuserfields" name="hiddenuserfields[]" size="10" multiple="multiple">'.$fieldoptions.'</select>' );
////////////////////////////////////////////////////////////////////
/// SECURITY config variables
////////////////////////////////////////////////////////////////////
$security = array();
/// displayloginfailures
unset($options);
$options[''] = get_string('nobody');
$options['admin'] = get_string('administrators');
$options['teacher'] = get_string('administratorsandteachers');
$options['everybody'] = get_string('everybody');
$security['displayloginfailures'] = new configvar (get_string('configdisplayloginfailures', 'admin'),
choose_from_menu($options, 'displayloginfailures', $config->displayloginfailures, '', '', '', true) );
/// notifyloginfailures
unset($options);
$options[''] = get_string('nobody');
$options['mainadmin'] = get_string('administrator');
$options['alladmins'] = get_string('administratorsall');
$security['notifyloginfailures'] = new configvar (get_string('confignotifyloginfailures', 'admin'),
choose_from_menu($options, 'notifyloginfailures', $config->notifyloginfailures, '', '', '', true) );
/// notifyloginthreshold
unset($options);
for ($i=1; $i<=100; $i++) {
$options[$i] = "$i";
}
$security['notifyloginthreshold'] = new configvar (get_string('confignotifyloginthreshold', 'admin'),
choose_from_menu($options, 'notifyloginthreshold', $config->notifyloginthreshold, '', '', '', true) );
/// secureforms
$security['secureforms'] = new configvar (get_string('configsecureforms', 'admin'),
choose_from_menu ($noyesoptions, 'secureforms', $config->secureforms, '', '', '', true) );
/// loginhttps
$security['loginhttps'] = new configvar (get_string('configloginhttps', 'admin'),
choose_from_menu ($noyesoptions, 'loginhttps', $config->loginhttps, '', '', '', true) );
/// runclamonupload
$security['runclamonupload'] = new configvar (get_string('configrunclamonupload', 'admin'),
choose_from_menu($noyesoptions, 'runclamonupload', $config->runclamonupload, '', '', '', true) );
/// pathtoclam
$security['pathtoclam'] = new configvar (get_string('configpathtoclam', 'admin'),
'<input type="text" name="pathtoclam" size="30" value="'.$config->pathtoclam.'" alt="pathtoclam" />' );
/// quarantinedir
$security['quarantinedir'] = new configvar (get_string('configquarantinedir', 'admin'),
'<input type="text" name="quarantinedir" size="30" value="'.$config->quarantinedir.'" alt="quarantinedir" />' );
/// clamfailureonupload
unset($options);
$options['donothing'] = get_string('configclamdonothing', 'admin');
$options['actlikevirus'] = get_string('configclamactlikevirus', 'admin');
$security['clamfailureonupload'] = new configvar (get_string('configclamfailureonupload', 'admin'),
choose_from_menu($options, 'clamfailureonupload', $config->clamfailureonupload, '', '', '', true) );
////////////////////////////////////////////////////////////////////
/// MAINTENANCE config variables
////////////////////////////////////////////////////////////////////
$maintenance = array();
/// longtimenosee
unset($options);
$options[0] = get_string('never');
$options[1000] = get_string('numdays', '', 1000);
$options[365] = get_string('numdays', '', 365);
$options[180] = get_string('numdays', '', 180);
$options[150] = get_string('numdays', '', 150);
$options[120] = get_string('numdays', '', 120);
$options[90] = get_string('numdays', '', 90);
$options[60] = get_string('numdays', '', 60);
$options[30] = get_string('numdays', '', 30);
$options[21] = get_string('numdays', '', 21);
$options[14] = get_string('numdays', '', 14);
$options[7] = get_string('numdays', '', 7);
$maintenance['longtimenosee'] = new configvar (get_string('configlongtimenosee', 'admin'),
choose_from_menu ($options, 'longtimenosee', $config->longtimenosee, '', '', '', true) );
/// deleteunconfirmed
unset($options);
$options[0] = get_string('never');
$options[168] = get_string('numdays', '', 7);
$options[144] = get_string('numdays', '', 6);
$options[120] = get_string('numdays', '', 5);
$options[96] = get_string('numdays', '', 4);
$options[72] = get_string('numdays', '', 3);
$options[48] = get_string('numdays', '', 2);
$options[24] = get_string('numdays', '', 1);
$options[12] = get_string('numhours', '', 12);
$options[6] = get_string('numhours', '', 6);
$options[1] = get_string('numhours', '', 1);
$maintenance['deleteunconfirmed'] = new configvar (get_string('configdeleteunconfirmed', 'admin'),
choose_from_menu ($options, 'deleteunconfirmed', $config->deleteunconfirmed, '', '', '', true) );
/// loglifetime
unset($options);
$options[0] = get_string('neverdeletelogs');
$options[1000] = get_string('numdays', '', 1000);
$options[365] = get_string('numdays', '', 365);
$options[180] = get_string('numdays', '', 180);
$options[150] = get_string('numdays', '', 150);
$options[120] = get_string('numdays', '', 120);
$options[90] = get_string('numdays', '', 90);
$options[60] = get_string('numdays', '', 60);
$options[30] = get_string('numdays', '', 30);
$maintenance['loglifetime'] = new configvar (get_string('configloglifetime', 'admin'),
choose_from_menu ($options, 'loglifetime', $config->loglifetime, '', '', '', true) );
////////////////////////////////////////////////////////////////////
/// MAIL config variables
////////////////////////////////////////////////////////////////////
$mail = array();
/// smtphosts
$mail['smtphosts'] = new configvar (get_string('configsmtphosts', 'admin'),
'<input name="smtphosts" type="text" size="30" value="'.s($config->smtphosts).'" alt="smtphosts" />' );
/// smtpuser
$mail['smtpuser'] = new configvar (get_string('configsmtpuser', 'admin'),
'<input name="smtpuser" type="text" size="10" value="'.s($config->smtpuser).'" alt="smtpuser" />' );
/// smtppass
$mail['smtppass'] = new configvar ('',
'<input name="smtppass" type="password" size="10" value="'.s($config->smtppass).'" alt="smtppass" />' );
/// noreplyaddress
$mail['noreplyaddress'] = new configvar (get_string('confignoreplyaddress', 'admin'),
'<input name="noreplyaddress" type="text" size="30" value="'.s($config->noreplyaddress).'" alt="noreplyaddress" />' );
/// digestmailtime
$hours = array();
for ($i=0; $i<=23; $i++) {
$hours[$i] = sprintf("%02d",$i);
}
$mail['digestmailtime'] = new configvar (get_string('configdigestmailtime', 'admin'),
choose_from_menu($hours, 'digestmailtime', $config->digestmailtime, '', '', 0, true) );
/// allowemailaddresses
$mail['allowemailaddresses'] = new configvar (get_string('configallowemailaddresses', 'admin'),
'<input name="allowemailaddresses" type="text" size="60" value="'.s($config->allowemailaddresses).'" alt="allowemailaddresses" />' );
/// denyemailaddresses
$mail['denyemailaddresses'] = new configvar (get_string('configdenyemailaddresses', 'admin'),
'<input name="denyemailaddresses" type="text" size="60" value="'.s($config->denyemailaddresses).'" alt="denyemailaddresses" />' );
if (!empty($CFG->unicodedb)) { ///These options are only available if running under unicodedb
/// sitemailcharset
unset($options);
unset($charsets);
$charsets = get_list_of_charsets();
$options['0'] = get_string('none');
$options = array_merge($options, $charsets);
$mail['sitemailcharset'] = new configvar (get_string('configsitemailcharset', 'admin'),
choose_from_menu($options, 'sitemailcharset', $config->sitemailcharset, '', '', '', true));
/// allowusermailcharset
$mail['allowusermailcharset'] = new configvar (get_string('configallowusermailcharset', 'admin'),
choose_from_menu($noyesoptions, 'allowusermailcharset', $config->allowusermailcharset, '', '', '', true));
}
/// enable stats
if (empty($CFG->disablestatsprocessing)) {
$stats['enablestats'] = new configvar (get_string('configenablestats','admin'),
choose_from_menu($noyesoptions, 'enablestats', $config->enablestats, '', '', '', true) );
unset($options);
$options['none'] = get_string('none');
$options[60*60*24*7] = get_string('numweeks','moodle',1);
$options[60*60*24*14] = get_string('numweeks','moodle',2);
$options[60*60*24*21] = get_string('numweeks','moodle',3);
$options[60*60*24*28] = get_string('nummonths','moodle',1);
$options[60*60*24*56] = get_string('nummonths','moodle',2);
$options[60*60*24*84] = get_string('nummonths','moodle',3);
$options[60*60*24*112] = get_string('nummonths','moodle',4);
$options[60*60*24*140] = get_string('nummonths','moodle',5);
$options[60*60*24*168] = get_string('nummonths','moodle',6);
$options['all'] = get_string('all');
$stats['statsfirstrun'] = new configvar (get_string('configstatsfirstrun','admin'),
choose_from_menu($options,'statsfirstrun',$config->statsfirstrun,'','','',true) );
unset($options);
$options[0] = get_string('untilcomplete');
$options[60*60] = '1 '.get_string('hour');
$options[60*60*2] = '2 '.get_string('hours');
$options[60*60*3] = '3 '.get_string('hours');
$options[60*60*4] = '4 '.get_string('hours');
$options[60*60*5] = '5 '.get_string('hours');
$options[60*60*6] = '6 '.get_string('hours');
$options[60*60*7] = '7 '.get_string('hours');
$options[60*60*8] = '8 '.get_string('hours');
if (empty($config->statsruntimestarthour)) {
$config->statsruntimestarthour = 0;
}
if (empty($config->statsruntimestartminute)) {
$config->statsruntimestartminute = 0;
}
$stats['statsmaxruntime'] = new configvar (get_string('configstatsmaxruntime','admin'),
choose_from_menu($options,'statsmaxruntime',$config->statsmaxruntime,'','','',true) );
$stats['statsruntimestart'] = new configvar (get_string('configstatsruntimestart','admin'),
print_time_selector("statsruntimestarthour","statsruntimestartminute",make_timestamp(2000,1,1,$config->statsruntimestarthour,$config->statsruntimestartminute),5,true) );
$stats['statsuserthreshold'] = new configvar (get_string('configstatsuserthreshold','admin'),
'<input type="text" name="statsuserthreshold" size="4" value="'.$config->statsuserthreshold.'" />');
}
////////////////////////////////////////////////////////////////////
$configvars['interface'] = $interface;
$configvars['security'] = $security;
$configvars['operatingsystem'] = $operatingsystem;
$configvars['maintenance'] = $maintenance;
$configvars['mail'] = $mail;
$configvars['user'] = $user;
$configvars['permissions'] = $permissions;
$configvars['requestedcourse'] = $reqcourse;
$configvars['misc'] = $misc;
if (empty($CFG->disablestatsprocessing)) {
$configvars['stats'] = $stats;
}
?>

View File

@ -356,6 +356,10 @@
require_once("$CFG->dirroot/lib/locallib.php");
upgrade_local_db("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards
/// Check for new groups and upgrade if necessary. TODO:
require_once("$CFG->dirroot/group/db/upgrade.php");
upgrade_group_db("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards
/// just make sure upgrade logging is properly terminated
upgrade_log_finish();

View File

@ -224,7 +224,7 @@
/// In the .html file below we loop through these results and exclude any in $contextusers
echo '<div align="center">'.$strcurrentcontext.': '.print_context_name($context).'<br/>';
echo $strroletoassign.': ';
echo '<label for="jump">'.$strroletoassign.'</label>: ';
$assignableroles = array('0'=>get_string('listallroles', 'role').'...') + $assignableroles;
popup_form("$CFG->wwwroot/$CFG->admin/roles/assign.php?userid=$userid&amp;courseid=$courseid&amp;contextid=$contextid&amp;roleid=",
$assignableroles, 'switchrole', $roleid, '');

View File

@ -304,8 +304,8 @@ if ($um->preprocess_files() && confirm_sesskey()) {
if (!$course[$i]) {
notify(get_string('coursegroupunknown','error',$addgroup[$i]));
} else {
if ($group = get_record("groups","courseid",$course[$i]->id,"name",$addgroup[$i])) {
$groupid[$i] = $group->id;
if ($groupid = groups_get_group_by_name($course[$i]->id, $addgroup[$i])) { //TODO:check.
$groupid[$i] = $groupid;
} else {
notify(get_string('groupunknown','error',$addgroup[$i]));
}

View File

@ -1,70 +0,0 @@
<?php
if (!isset($form->dbhost)) {
$form->dbhost = '';
}
if (!isset($form->dbname)) {
$form->dbname = '';
}
if (!isset($form->dbuser)) {
$form->dbuser = '';
}
if (!isset($form->dbpass)) {
$form->dbpass = '';
}
if (!isset($form->dbcluster)) {
$form->dbcluster = '';
}
if (!isset($form->pathtopgdump)) {
$form->pathtopgdump = '';
}
if (!isset($form->pathtopsql)) {
$form->pathtopsql = '';
}
?>
<form name="migratefrom" action="utfdbmigrate.php" method="POST">
<input name="migrate" type="hidden" value="1" />
<input name="sesskey" type="hidden" value="<?php echo sesskey() ?>" />
<?php if (isset($err["dbconnect"])) formerr($err["dbconnect"]); ?>
<?php if (isset($err["pathtopgdump"])) formerr($err["pathtopgdump"]); ?>
<?php if (isset($err["pathtopsql"])) formerr($err["pathtopsql"]); ?>
<table cellpadding="9" cellspacing="0" width="500">
<tr valign="top">
<td align="right"><?php print_string("dbhost", "install") ?>:</td>
<td><input type="text" name="dbhost" value="<?php p($form->dbhost) ?>" />
</td>
</tr>
<tr valign="top">
<td align="right"><?php print_string("database", "install") ?>:</td>
<td><input type="text" name="dbname" value="<?php p($form->dbname) ?>" />
</td>
</tr>
<tr valign="top">
<td align="right"><?php print_string("user") ?>:</td>
<td><input type="text" name="dbuser" value="<?php p($form->dbuser) ?>" />
</td>
</tr>
<tr valign="top">
<td align="right"><?php print_string("password") ?>:</td>
<td><input type="text" name="dbpass" value="<?php p($form->dbpass) ?>" />
</td>
</tr>
<tr valign="top">
<td align="right"><?php print_string("pgcluster", "admin") ?>:</td>
<td><input type="text" name="dbcluster" value="<?php p($form->dbcluster) ?>" />
<td><?php print_string("pgclusterdescription", "admin") ?></td>
</tr>
<tr valign="top">
<td align="right" nowrap="nowrap"><?php print_string("pathtopgdump","admin") ?>:</td>
<td><input type="text" name="pathtopgdump" value="<?php p($form->pathtopgdump) ?>" />
<td><?php print_string("pathtopgdumpdesc","admin"); ?></td>
</tr>
<tr valign="top">
<td align="right" nowrap="nowrap"><?php print_string("pathtopsql","admin") ?>:</td>
<td><input type="text" name="pathtopsql" value="<?php p($form->pathtopsql) ?>" />
<td><?php print_string("pathtopsqldesc","admin"); ?></td>
</tr>
</table>
<center>
<input type="submit" value="<?php print_string('continue') ?>"/>
&nbsp;<input type="button" value="<?php print_string('cancel') ?>" onclick="javascript:history.go(-1)" />
</center>

File diff suppressed because it is too large Load Diff

View File

@ -141,6 +141,14 @@ class get_db_directories extends XMLDBAction {
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
}
}
/// Now, groups
$dbdir->path = $CFG->dirroot . '/group/db';
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
}
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
/// Sort by key
ksort($XMLDB->dbdirs);

View File

@ -1642,7 +1642,7 @@
$status2 = true;
//Get groups
$groups = get_records("groups","courseid",$preferences->backup_course);
$groups = get_groups($preferences->backup_course); //TODO:check.
//Pring groups header
if ($groups) {
@ -1692,7 +1692,7 @@
$status = true;
//Get groups_members
$groups_members = get_records("groups_members","groupid",$groupid);
$groups_members = groups_get_members($groupid); //TODO:check.
//Pring groups_members header
if ($groups_members) {
@ -1869,8 +1869,8 @@
//Iterate
foreach ($list as $dir) {
//Look for dir like group in groups table
$data = get_record ('groups', 'courseid', $preferences->backup_course,
'id',$dir);
$data = groups_group_belongs_to_course($dir, $preferences->backup_course);
//TODO:check. get_record ('groups', 'courseid', $preferences->backup_course,'id',$dir);
//If exists, copy it
if ($data) {
$status = backup_copy_file($rootdir."/".$dir,

View File

@ -1,42 +0,0 @@
<?php // $Id$
function migrate2utf8_backup_ids_info($recordid){
global $CFG, $globallang;
/// Some trivial checks
if (empty($recordid)) {
log_the_problem_somewhere();
return false;
}
if (!$backupids= get_record('backup_ids', 'id', $recordid)) {
log_the_problem_somewhere();
return false;
}
if ($globallang) {
$fromenc = $globallang;
} else {
$sitelang = $CFG->lang;
$courselang = null;
$userlang = null; //N.E.!!
$fromenc = get_original_encoding($sitelang, $courselang, $userlang);
}
/// Initialise $result
$result = $backupids->info;
/// Convert the text
if (($fromenc != 'utf-8') && ($fromenc != 'UTF-8')) {
$result = utfconvert($backupids->info, $fromenc);
$newbackupids = new object;
$newbackupids->id = $recordid;
$newbackupids->info = $result;
migrate2utf8_update_record('backup_ids',$newbackupids);
}
/// And finally, just return the converted field
return $result;
}
?>

View File

@ -1,36 +0,0 @@
<DBMIGRATION type="backup" VERSION="2005120100">
<TABLES>
<TABLE name="backup_config">
<FIELDS>
<FIELD name="name" method="NO_CONV" type="varchar" length="255" dropindex="name" adduniqueindex="name (name(255))"/>
<FIELD name="value" method="NO_CONV" type="varchar" length="255" />
</FIELDS>
</TABLE>
<TABLE name="backup_courses">
<FIELDS>
<FIELD name="laststatus" method="NO_CONV" type="char" length="1" />
</FIELDS>
</TABLE>
<TABLE name="backup_files">
<FIELDS>
<FIELD name="file_type" method="NO_CONV" type="varchar" length="10" dropindex="backup_files_uk" />
<FIELD name="path" method="NO_CONV" type="varchar" length="255" adduniqueindex="backup_files_uk (backup_code, file_type(10), path(255))"/>
</FIELDS>
</TABLE>
<TABLE name="backup_ids">
<FIELDS>
<FIELD name="table_name" method="NO_CONV" type="varchar" length="30" dropindex="backup_ids_uk" adduniqueindex=" backup_ids_uk(backup_code, table_name(30), old_id)"/>
<FIELD name="info" method="PHP_FUNCTION" type="mediumtext" length="0">
<PHP_FUNCTION>
migrate2utf8_backup_ids_info(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="backup_log">
<FIELDS>
<FIELD name="info" method="NO_CONV" type="varchar" length="255" />
</FIELDS>
</TABLE>
</TABLES>
</DBMIGRATION>

View File

@ -88,7 +88,7 @@ class block_admin extends block_list {
if (($course->groupmode || !$course->groupmodeforce) && has_capability('moodle/course:managegroups', $context) && ($course->id!==SITEID)) {
$strgroups = get_string('groups');
$this->content->items[]='<a title="'.$strgroups.'" href="'.$CFG->wwwroot.'/course/groups.php?id='.$this->instance->pageid.'">'.$strgroups.'</a>';
$this->content->items[]='<a title="'.$strgroups.'" href="'.groups_home_url($this->instance->pageid).'">'.$strgroups.'</a>';
$this->content->icons[]='<img src="'.$CFG->pixpath.'/i/group.gif" alt="" />';
}

View File

@ -1,190 +0,0 @@
<?php // $Id$
function migrate2utf8_block_instance_configdata($recordid){
global $CFG, $globallang;
$blockinstance = get_record('block_instance','id',$recordid);
//get block instance type, we only need to worry about HTML blocks... right?????????
$blocktype = get_record('block','id',$blockinstance->blockid);
if ($blocktype -> name == 'html') {
///find course
if ($globallang) {
$fromenc = $globallang;
} else {
$sitelang = $CFG->lang;
$courselang = get_course_lang($blockinstance->pageid); //Non existing!
$userlang = get_main_teacher_lang($blockinstance->pageid); //N.E.!!
$fromenc = get_original_encoding($sitelang, $courselang, $userlang);
}
$blah = unserialize(base64_decode($blockinstance->configdata));
/// We are going to use textlib facilities
/// Convert the text
$blah->title = utfconvert($blah->title, $fromenc, false);
$blah->text = utfconvert($blah->text, $fromenc, false);
$blockinstance->configdata = base64_encode(serialize($blah));
migrate2utf8_update_record('block_instance',$blockinstance);
return $blah;
} else if ($blocktype -> name == 'rss_client'){
///find course
if ($globallang) {
$fromenc = $globallang;
} else {
$sitelang = $CFG->lang;
$courselang = get_course_lang($blockinstance->pageid); //Non existing!
$userlang = get_main_teacher_lang($blockinstance->pageid); //N.E.!!
$fromenc = get_original_encoding($sitelang, $courselang, $userlang);
}
$blah = unserialize(base64_decode($blockinstance->configdata));
/// We are going to use textlib facilities
/// Convert the text
$blah->title = utfconvert($blah->title, $fromenc, false);
$blockinstance->configdata = base64_encode(serialize($blah));
migrate2utf8_update_record('block_instance',$blockinstance);
return $blah;
} else if ($blocktype -> name == 'glossary_random'){
///find course
if ($globallang) {
$fromenc = $globallang;
} else {
$sitelang = $CFG->lang;
$courselang = get_course_lang($blockinstance->pageid); //Non existing!
$userlang = get_main_teacher_lang($blockinstance->pageid); //N.E.!!
$fromenc = get_original_encoding($sitelang, $courselang, $userlang);
}
$blah = unserialize(base64_decode($blockinstance->configdata));
/// We are going to use textlib facilities
/// Convert the text
$blah->title = utfconvert($blah->title, $fromenc, false);
$blah->addentry = utfconvert($blah->addentry, $fromenc, false);
$blah->viewglossary = utfconvert($blah->viewglossary, $fromenc, false);
$blah->invisible = utfconvert($blah->invisible, $fromenc, false);
$blockinstance->configdata = base64_encode(serialize($blah));
migrate2utf8_update_record('block_instance',$blockinstance);
return $blah;
}
}
function migrate2utf8_block_pinned_configdata($recordid){
global $CFG, $globallang;
$blockpinned = get_record('block_pinned','id',$recordid);
//get block instance type, we only need to worry about HTML blocks... right?????????
$blocktype = get_record('block','id',$blockpinned->blockid);
if ($blocktype -> name == 'html') {
///find course
if ($globallang) {
$fromenc = $globallang;
} else {
$sitelang = $CFG->lang;
$courselang = get_course_lang($blockpinned->pageid); //Non existing!
$userlang = get_main_teacher_lang($blockpinned->pageid); //N.E.!!
$fromenc = get_original_encoding($sitelang, $courselang, $userlang);
}
$blah = unserialize(base64_decode($blockpinned->configdata));
/// We are going to use textlib facilities
/// Convert the text
$blah->title = utfconvert($blah->title, $fromenc, false);
$blah->text = utfconvert($blah->text, $fromenc, false);
$blockpinned->configdata = base64_encode(serialize($blah));
migrate2utf8_update_record('blockpinned',$blockpinned);
return $blah;
} else if ($blocktype -> name == 'rss_client'){
///find course
if ($globallang) {
$fromenc = $globallang;
} else {
$sitelang = $CFG->lang;
$courselang = get_course_lang($blockpinned->pageid); //Non existing!
$userlang = get_main_teacher_lang($blockpinned->pageid); //N.E.!!
$fromenc = get_original_encoding($sitelang, $courselang, $userlang);
}
$blah = unserialize(base64_decode($blockpinned->configdata));
/// We are going to use textlib facilities
/// Convert the text
$blah->title = utfconvert($blah->title, $fromenc, false);
$blockpinned->configdata = base64_encode(serialize($blah));
migrate2utf8_update_record('blockpinned',$blockblockpinned);
return $blah;
} else if ($blocktype -> name == 'glossary_random'){
///find course
if ($globallang) {
$fromenc = $globallang;
} else {
$sitelang = $CFG->lang;
$courselang = get_course_lang($blockpinned->pageid); //Non existing!
$userlang = get_main_teacher_lang($blockpinned->pageid); //N.E.!!
$fromenc = get_original_encoding($sitelang, $courselang, $userlang);
}
$blah = unserialize(base64_decode($blockpinned->configdata));
/// We are going to use textlib facilities
/// Convert the text
$blah->title = utfconvert($blah->title, $fromenc, false);
$blah->addentry = utfconvert($blah->addentry, $fromenc, false);
$blah->viewglossary = utfconvert($blah->viewglossary, $fromenc, false);
$blah->invisible = utfconvert($blah->invisible, $fromenc, false);
$blockinstance->configdata = base64_encode(serialize($blah));
migrate2utf8_update_record('block_instance',$blockinstance);
return $blah;
}
}
?>

View File

@ -1,31 +0,0 @@
<DBMIGRATION type="blocks" VERSION="2005120100">
<TABLES>
<TABLE name="block">
<FIELDS>
<FIELD name="name" method="NO_CONV" type="varchar" length="40" />
</FIELDS>
</TABLE>
<TABLE name="block_instance">
<FIELDS>
<FIELD name="pagetype" method="NO_CONV" type="varchar" length="20" dropindex="pagetype" addindex="pagetype (pagetype(20))"/>
<FIELD name="position" method="NO_CONV" type="varchar" length="10" />
<FIELD name="configdata" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_block_instance_configdata(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="block_pinned">
<FIELDS>
<FIELD name="pagetype" method="NO_CONV" type="varchar" length="20" dropindex="pagetype" addindex="pagetype (pagetype(20))"/>
<FIELD name="position" method="NO_CONV" type="varchar" length="10" />
<FIELD name="configdata" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_block_pinned_configdata(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
</TABLES>
</DBMIGRATION>

View File

@ -50,8 +50,8 @@ class block_online_users extends block_base {
//Add this to the SQL to show only group users
if ($currentgroup !== NULL) {
$groupmembers = ", {$CFG->prefix}groups_members gm ";
$groupselect .= " AND u.id = gm.userid AND gm.groupid = '$currentgroup'";
$groupmembers = ', '.groups_members_from_sql(); //TODO: ", {$CFG->prefix}groups_members gm ";
$groupselect .= groups_members_where_sql($currentgroup, 'u.id'); //" AND u.id = gm.userid AND gm.groupid = '$currentgroup'";
}
if ($COURSE->id == SITEID) { // Site-level

View File

@ -1,204 +0,0 @@
<?php // $Id$
die; //must be fixed before enabling again, see SC#971
// All of this is standard Moodle fixtures
require_once('../config.php');
require_once($CFG->dirroot .'/course/lib.php');
require_once($CFG->dirroot .'/lib/blocklib.php');
require_once($CFG->dirroot .'/mod/resource/lib.php');
require_once($CFG->dirroot .'/mod/forum/lib.php');
optional_param('blockaction');
optional_param('instanceid', 0, PARAM_INT);
optional_param('blockid', 0, PARAM_INT);
require_login();
// Begin snippet -----------------------------------------------------------------
// This snippet should normally be defined in another file, but I 've put it all
// in here to keep it simple.
// First of all define the string identifier for this "type" of page.
define('MOODLE_PAGE_TEST', 'testpage');
// Also, define identifiers for any non-standard block positions we want to support.
define('BLOCK_POS_CENTERUP', 'cu');
define('BLOCK_POS_CENTERDOWN', 'cd');
// The actual Page derived class
class page_test extends page_base {
// Mandatory; should return our identifier.
function get_type() {
return MOODLE_PAGE_TEST;
}
// For this test page, only admins are going to be allowed editing (for simplicity).
function user_allowed_editing() {
return isadmin();
}
// Also, admins are considered to have "always on" editing (I wanted to avoid duplicating
// the code that turns editing on/off here; you can roll your own or copy course/view.php).
function user_is_editing() {
return isadmin();
}
// Simple method that accepts one parameter and prints the header. Here we just ignore
// the parameter entirely.
function print_header($title) {
print_header("Page testing page", 'SAMPLE CUSTOM PAGE', 'home');
}
// This should point to the script that displays us; it's straightforward in this case.
function url_get_path() {
global $CFG;
return $CFG->wwwroot .'/blocks/pagedemo.php';
}
// We do not need any special request variables such as ID in this case, so we 're not
// going to have to override url_get_parameters() here; the default suits us nicely.
// Having defined all identifiers we need, here we declare which block positions we are
// going to support.
function blocks_get_positions() {
return array(BLOCK_POS_LEFT, BLOCK_POS_RIGHT, BLOCK_POS_CENTERUP, BLOCK_POS_CENTERDOWN);
}
// And here we declare where new blocks will appear (arbitrary choice).
function blocks_default_position() {
return BLOCK_POS_CENTERUP;
}
// Since we 're not going to be creating multiple instances of this "page" (as we do with
// courses), we don't need to provide default blocks. Otherwise we 'd need to override
// the blocks_get_default() method.
// And finally, a little block move logic. Given a block's previous position and where
// we want to move it to, return its new position. Pretty self-documenting.
function blocks_move_position(&$instance, $move) {
if($instance->position == BLOCK_POS_LEFT && $move == BLOCK_MOVE_RIGHT) {
return BLOCK_POS_CENTERUP;
} else if ($instance->position == BLOCK_POS_RIGHT && $move == BLOCK_MOVE_LEFT) {
return BLOCK_POS_CENTERUP;
} else if (($instance->position == BLOCK_POS_CENTERUP || $instance->position == BLOCK_POS_CENTERDOWN) && $move == BLOCK_MOVE_LEFT) {
return BLOCK_POS_LEFT;
} else if (($instance->position == BLOCK_POS_CENTERUP || $instance->position == BLOCK_POS_CENTERDOWN) && $move == BLOCK_MOVE_RIGHT) {
return BLOCK_POS_RIGHT;
} else if ($instance->position == BLOCK_POS_CENTERUP && $move == BLOCK_MOVE_DOWN) {
return BLOCK_POS_CENTERDOWN;
} else if ($instance->position == BLOCK_POS_CENTERDOWN && $move == BLOCK_MOVE_UP) {
return BLOCK_POS_CENTERUP;
}
return $instance->position;
}
}
// End snippet -------------------------------------------------------------------
/// Bounds for block widths on this page
define('BLOCK_L_MIN_WIDTH', 160);
define('BLOCK_L_MAX_WIDTH', 210);
define('BLOCK_R_MIN_WIDTH', 160);
define('BLOCK_R_MAX_WIDTH', 210);
define('BLOCK_C_MIN_WIDTH', 250);
define('BLOCK_C_MAX_WIDTH', 350);
// Before creating our page object, we need to map our page identifier to the actual name
// of the class which will be handling its operations. Pretty simple, but essential.
page_map_class(MOODLE_PAGE_TEST, 'page_test');
// Now, create our page object. The identifier "1" is passed arbitrarily because we don't
// have multiple "testpages"; if we did, that would be the "testpageid" from the database.
$PAGE = page_create_object(MOODLE_PAGE_TEST, 1);
$PAGE->print_header(NULL);
$editing = $PAGE->user_is_editing();
// That's it! From now on, everything is simply copy-pasted from course/view.php with a few
// minor tweaks to display the page layout!
// Calculate the preferred width for left, right and center (both center positions will use the same)
if (empty($preferred_width_left)) {
$preferred_width_left = blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]);
}
if (empty($preferred_width_right)) {
$preferred_width_right = blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]);
}
if (empty($preferred_width_centerup)) {
$preferred_width_centerup = blocks_preferred_width($pageblocks[BLOCK_POS_CENTERUP]);
}
if (empty($preferred_width_centerdown)) {
$preferred_width_centerdown = blocks_preferred_width($pageblocks[BLOCK_POS_CENTERDOWN]);
}
$preferred_width_left = min($preferred_width_left, BLOCK_L_MAX_WIDTH);
$preferred_width_left = max($preferred_width_left, BLOCK_L_MIN_WIDTH);
$preferred_width_right = min($preferred_width_right, BLOCK_R_MAX_WIDTH);
$preferred_width_right = max($preferred_width_right, BLOCK_R_MIN_WIDTH);
$preferred_width_center = max($preferred_width_centerup, $preferred_width_centerdown);
$preferred_width_center = min($preferred_width_center, BLOCK_C_MAX_WIDTH);
$preferred_width_center = max($preferred_width_center, BLOCK_C_MIN_WIDTH);
// Display the blocks and allow blocklib to handle any block action requested
$pageblocks = blocks_get_by_page($PAGE);
if($editing) {
if (!empty($blockaction) && confirm_sesskey()) {
if (!empty($blockid)) {
blocks_execute_action($PAGE, $pageblocks, strtolower($blockaction), intval($blockid));
}
else if (!empty($instanceid)) {
$instance = blocks_find_instance($instanceid, $pageblocks);
blocks_execute_action($PAGE, $pageblocks, strtolower($blockaction), $instance);
}
// This re-query could be eliminated by judicious programming in blocks_execute_action(),
// but I'm not sure if it's worth the complexity increase...
$pageblocks = blocks_get_by_page($PAGE);
}
}
// The actual display logic is here
echo '<table style="width: 100%;"><tr>';
if(blocks_have_content($pageblocks,BLOCK_POS_LEFT) || $editing) {
echo '<td style="vertical-align: top; width: '.$preferred_width_left.'px;">';
blocks_print_group($PAGE, $pageblocks,BLOCK_POS_LEFT);
echo '</td>';
}
echo '<td style="border: 1px black solid; width: '.$preferred_width_center.'px;"><p style="text-align: center; padding: 10px; background: black; color: white;">Center-up position:</p>';
if(blocks_have_content($pageblocks,BLOCK_POS_CENTERUP) || $editing) {
blocks_print_group($PAGE, $pageblocks,BLOCK_POS_CENTERUP);
}
echo '<div style="padding: 10px; background: gold; text-align: center;">Content Here';
print_object(make_timestamp(2005, 6, 1, 0, 0, 0));
echo '</div>';
echo '<p style="text-align: center; padding: 10px; background: black; color: white;">Center-down position:</p>';
if(blocks_have_content($pageblocks,BLOCK_POS_CENTERDOWN) || $editing) {
blocks_print_group($PAGE, $pageblocks,BLOCK_POS_CENTERDOWN);
}
echo '</td>';
if(blocks_have_content($pageblocks,BLOCK_POS_RIGHT) || $editing) {
echo '<td style="vertical-align: top; width: '.$preferred_width_right.'px;">';
blocks_print_group($PAGE, $pageblocks,BLOCK_POS_RIGHT);
if ($editing) {
blocks_print_adminblock($PAGE, $pageblocks);
}
echo '</td>';
}
// Finished! :-)
echo '</tr></table>';
print_footer();
?>

View File

@ -127,10 +127,10 @@ class block_quiz_results extends block_base {
}
// Now find which groups these users belong in
$groupofuser = get_records_sql(
$groupofuser = groups_get_groups_users($userids, $courseid); /*TODO: get_records_sql(
'SELECT m.userid, m.groupid, g.name FROM '.$CFG->prefix.'groups g LEFT JOIN '.$CFG->prefix.'groups_members m ON g.id = m.groupid '.
'WHERE g.courseid = '.$courseid.' AND m.userid IN ('.implode(',', $userids).')'
);
);*/
$groupgrades = array();

View File

@ -1,140 +0,0 @@
<?php // $Id$
function migrate2utf8_block_rss_client_title($recordid){
global $CFG, $globallang;
/// Some trivial checks
if (empty($recordid)) {
log_the_problem_somewhere();
return false;
}
if (!$rssclient = get_record('block_rss_client','id',$recordid)) {
log_the_problem_somewhere();
return false;
}
if ($globallang) {
$fromenc = $globallang;
} else {
$user = get_record('user','id',$rssclient->userid);
$sitelang = $CFG->lang;
$courselang = NULL; //Non existing!
$userlang = $user->lang; //N.E.!!
$fromenc = get_original_encoding($sitelang, $courselang, $userlang);
}
/// We are going to use textlib facilities
/// Convert the text
if (($fromenc != 'utf-8') && ($fromenc != 'UTF-8')) {
$result = utfconvert($rssclient->title, $fromenc);
$newrssclient = new object;
$newrssclient->id = $recordid;
$newrssclient->title = $result;
migrate2utf8_update_record('block_rss_client',$newrssclient);
}
/// And finally, just return the converted field
return $result;
}
function migrate2utf8_block_rss_client_preferredtitle($recordid){
global $CFG, $globallang;
/// Some trivial checks
if (empty($recordid)) {
log_the_problem_somewhere();
return false;
}
$SQL = "SELECT brc.userid
FROM {$CFG->prefix}block_rss_client brc
WHERE brc.id = $recordid";
if (!$rssuserid = get_record_sql($SQL)) {
log_the_problem_somewhere();
return false;
}
if (!$rssclient = get_record('block_rss_client','id',$recordid)) {
log_the_problem_somewhere();
return false;
}
if ($globallang) {
$fromenc = $globallang;
} else {
$user = get_record('user','id',$rssuserid->userid);
$sitelang = $CFG->lang;
$courselang = NULL; //Non existing!
$userlang = $user->lang; //N.E.!!
$fromenc = get_original_encoding($sitelang, $courselang, $userlang);
}
/// We are going to use textlib facilities
/// Convert the text
if (($fromenc != 'utf-8') && ($fromenc != 'UTF-8')) {
$result = utfconvert($rssclient->preferredtitle, $fromenc);
$newrssclient = new object;
$newrssclient->id = $recordid;
$newrssclient->preferredtitle = $result;
migrate2utf8_update_record('block_rss_client',$newrssclient);
/// And finally, just return the converted field
}
return $result;
}
function migrate2utf8_block_rss_client_description($recordid){
global $CFG, $globallang;
/// Some trivial checks
if (empty($recordid)) {
log_the_problem_somewhere();
return false;
}
$SQL = "SELECT brc.userid
FROM {$CFG->prefix}block_rss_client brc
WHERE brc.id = $recordid";
if (!$rssuserid = get_record_sql($SQL)) {
log_the_problem_somewhere();
return false;
}
if (!$rssclient = get_record('block_rss_client','id',$recordid)) {
log_the_problem_somewhere();
return false;
}
if ($globallang) {
$fromenc = $globallang;
} else {
$user = get_record('user','id',$rssuserid->userid);
$sitelang = $CFG->lang;
$courselang = NULL; //Non existing!
$userlang = $user->lang; //N.E.!!
$fromenc = get_original_encoding($sitelang, $courselang, $userlang);
}
/// We are going to use textlib facilities
/// Convert the text
if (($fromenc != 'utf-8') && ($fromenc != 'UTF-8')) {
$result = utfconvert($rssclient->description, $fromenc);
$newrssclient = new object;
$newrssclient->id = $recordid;
$newrssclient->description = $result;
migrate2utf8_update_record('block_rss_client',$newrssclient);
}
/// And finally, just return the converted field
return $result;
}
?>

View File

@ -1,24 +0,0 @@
<DBMIGRATION type="blocks/rss_client" VERSION="2005120100">
<TABLES>
<TABLE name="block_rss_client">
<FIELDS>
<FIELD name="title" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_block_rss_client_title(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="preferredtitle" method="PHP_FUNCTION" type="varchar" length="64">
<PHP_FUNCTION>
migrate2utf8_block_rss_client_preferredtitle(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="description" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_block_rss_client_description(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="url" method="NO_CONV" type="varchar" length="255" />
</FIELDS>
</TABLE>
</TABLES>
</DBMIGRATION>

View File

@ -127,17 +127,18 @@ if (!$course = get_record('course', 'id', $courseid)) {
case 'group':
$thisgroup = get_record('groups', 'id', $filterselect);
if ($tagid || !empty($tag)) {
print_header("$course->shortname: $blogstring", $course->fullname,
if ($thisgroup = groups_get_group($filterselect, false)) { //TODO:
if ($tagid || !empty($tag)) {
print_header("$course->shortname: $blogstring", $course->fullname,
'<a href="'.$CFG->wwwroot.'/user/index.php?id='.$course->id.'&amp;group='.$filterselect.'">'.$thisgroup->name.'</a> ->
<a href="index.php?filtertype=group&amp;filterselect='.$filterselect.'">'. "$blogstring</a> -> $tagstring: $taginstance->text",'','',true,$PAGE->get_extra_header_string());
} else {
print_header("$course->shortname: $blogstring", $course->fullname,
} else {
print_header("$course->shortname: $blogstring", $course->fullname,
'<a href="'.$CFG->wwwroot.'/user/index.php?id='.$course->id.'&amp;group='.$filterselect.'">'.$thisgroup->name."</a> ->
$blogstring",'','',true,$PAGE->get_extra_header_string());
}
} else {
print_error('Unable to find group');
}
break;

View File

@ -84,7 +84,7 @@ switch ($filtertype) {
if ($CFG->bloglevel < BLOG_GROUP_LEVEL) {
error('Group blogs is not enabled');
}
if (!$group = get_record('groups','id',$groupid)) {
if (! $group = groups_get_group($groupid)) { //TODO:check.
error('Incorrect group id specified');
}
if (!$course = get_record('course', 'id', $group->courseid)) {

View File

@ -548,13 +548,20 @@
case 'group':
$SQL = 'SELECT '.$requiredfields.' FROM '.$CFG->prefix.'post p, '.$tagtablesql
.groups_members_from_sql().', '.$CFG->prefix.'user u
WHERE '.groups_members_where_sql($filterselect, 'p.userid').'
AND u.id = p.userid
AND u.deleted = 0
AND '.$permissionsql;
/*'SELECT '.$requiredfields.' FROM '.$CFG->prefix.'post p, '.$tagtablesql
.$CFG->prefix.'groups_members m, '.$CFG->prefix.'user u
WHERE p.userid = m.userid '.$tagquerysql.'
AND u.id = p.userid
AND m.groupid = '.$filterselect.'
AND u.deleted = 0
AND '.$permissionsql;
*/
break;
case 'user':

View File

@ -99,7 +99,8 @@
$info = $SITE->fullname;
break;
case 'group':
$info = get_field('groups', 'name', 'id', $id);
$group = groups_get_group($id, false);
$info = $group->name; //TODO: get_field('groups', 'name', 'id', $id)
break;
default:
$info = '';

View File

@ -413,7 +413,7 @@
break;
case 'group':
$groupid = optional_param('groupid', 0, PARAM_INT);
if(!($group = get_record('groups', 'id', $groupid) )) {
if (! ($group = groups_get_group($groupid))) { //TODO:check.
calendar_get_allowed_types($allowed);
$eventtype = 'select';
}
@ -604,14 +604,14 @@ function calendar_add_event_allowed($event) {
return has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_COURSE, $event->courseid));
case 'group':
if (!$group = get_record('groups', 'id', $event->groupid)) {
if (! groups_group_exists($event->groupid)) { //TODO:check.
return false;
}
// this is ok because if you have this capability at course level, you should be able
// to edit group calendar too
// there is no need to check membership, because if you have this capability
// you will have a role in this group context
return has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_GROUP, $group->id));
return has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_GROUP, $event->groupid));
case 'user':
if ($event->userid == $USER->id) {

View File

@ -214,6 +214,12 @@
$sesskey = !empty($USER->id) ? $USER->sesskey : '';
//DONOTCOMMIT: TODO:
if (debugging()) {
echo '<p>[ <a href="../group/groupui/?id='. $courseid .'">AJAX groups</a>
| <a href="../group/index.php?id='. $courseid .'">New groups</a> - debugging.]</p>';
}
/// Print out the complete form
print_heading(get_string('groups'));
@ -222,4 +228,4 @@
print_footer($course);
?>
?>

View File

@ -177,7 +177,7 @@ function print_recent_selector_form($course, $advancedfilter=0, $selecteduser=0,
$groupmode = groupmode($course);
if ($groupmode == VISIBLEGROUPS or ($groupmode and has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id)))) {
if ($groups = get_records_menu("groups", "courseid", $course->id, "name ASC", "id,name")) {
if ($groups_names = groups_get_groups_names($course->id)) { //TODO:check.
echo '<td><b>';
if ($groupmode == VISIBLEGROUPS) {
print_string('groupsvisible');
@ -185,7 +185,7 @@ function print_recent_selector_form($course, $advancedfilter=0, $selecteduser=0,
print_string('groupsseparate');
}
echo ':</b></td><td>';
choose_from_menu($groups, "selectedgroup", $selectedgroup, get_string("allgroups"), "", "");
choose_from_menu($groups_names, "selectedgroup", $selectedgroup, get_string("allgroups"), "", "");
echo '</td>';
}
}
@ -305,7 +305,7 @@ function build_logs_array($course, $user=0, $date=0, $order="l.time ASC", $limit
/// Getting all members of a group.
if ($groupid and !$user) {
if ($gusers = get_records('groups_members', 'groupid', $groupid)) {
if ($gusers = groups_get_members($groupid)) { //TODO:check.
$first = true;
foreach($gusers as $guser) {
if ($first) {

View File

@ -1,20 +0,0 @@
Moodle - Modular Object-Oriented Dynamic Learning Environment
http://moodle.org
Copyright (C) 1999-2004 Martin Dougiamas martin@dougiamas.com
http://dougiamas.com
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

View File

@ -1,38 +0,0 @@
<?PHP // $Id$
require("../config.php");
if (! $info = document_file("files.php", false)) {
error("404 - File Not Found");
}
$string = array();
if ($CFG->forcelogin) {
require_login();
}
include($info->filepath);
print_header();
$ulopen = false;
foreach ($string as $file => $filename) {
if (substr($file,0,1) == "-") {
if($ulopen) {
echo '</ul>';
}
echo '<h1>'.$filename.'</h1><ul>';
$ulopen = true;
} else {
echo '<li><a target="main" href="'.$CFG->wwwroot.'/doc/?file='.$file.'">'.$filename.'</a></li>';
}
}
if($ulopen) {
echo '</ul>';
}
// Sloppy way to produce valid markup... there should be a print_footer_minimal().
echo '</div></div></body></html>';
?>

View File

@ -1,131 +0,0 @@
body, td, th, li {
font-family: "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
}
th {
font-weight: bold;
}
a:link {
text-decoration: none;
color: blue;
}
a:visited {
text-decoration: none;
color: blue;
}
a:hover {
text-decoration: underline;
color: red;
}
form {
margin-bottom: 0;
}
li {
margin-bottom: 10px;
}
.question {
font-size: medium;
font-weight: bold;
font-family: "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
border: 1px dotted;
padding: 10px;
background-color: #EEEEEE;
}
.answer {
font-family: "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
font-size: medium;
border: none;
padding-left: 40px;
}
.normaltext {
font-family: "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
font-size: medium;
border: none;
margin-left: 30px;
}
.answercode {
font-family: "Courier New", Courier, mono;
font-size: small;
border: none;
padding-left: 60px;
}
.questionlink {
font-family: "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
font-size: medium;
border: none;
padding-left: 40px;
}
.examplecode {
font-family: "Courier New", Courier, mono;
font-size: small;
border: thin dashed #999999;
background-color: #FBFBFB;
margin: auto;
padding: 30px;
height: auto;
width: auto;
}
h1 {
font-weight: bold;
color: #000000;
background-color: #CCCCCC;
padding: 5px;
font-size: large;
border-width: 1px;
border-color: #CCCCCC;
-moz-border-radius: 10px;
}
h2 {
font-weight: bold;
color: #FFFFFF;
background-color: #666666;
padding: 5px;
font-size: medium;
border-width: 1px;
border-color: #666666;
-moz-border-radius: 10px;
}
h3 {
font-weight: normal;
color: #FFFFFF;
background-color: #666666;
padding: 5px;
font-size: medium;
-moz-border-radius: 10px;
}
.spaced {
margin-bottom: 30px;
}
ul {
margin-top: 10px;
}
.commandline {
font-family: "Courier New", Courier, mono;
font-size: x-small;
background-color: #FBFBFB;
margin: auto auto 20px 30px;
padding: 5px;
width: compact;
font-weight: bold;
border: 1px solid #999999;
white-space: nowrap;
clear: both;
float: none;
}

View File

@ -1,54 +0,0 @@
<?PHP // $Id$
require("../config.php");
$file = optional_param('file', "", PARAM_FILE); // docs file to view straight
$frame = optional_param('frame', "", PARAM_FILE); // docs file to view in frame
$sub = optional_param('sub', "", PARAM_CLEAN); // sub-section (named anchor)
if ($CFG->forcelogin) {
require_login();
}
if (!empty($sub)) {
$sub = '#'.s($sub);
} else {
$sub = "";
}
if (empty($file)) {
$include = false;
if (empty($frame)) {
$file = "intro.html";
} else {
$file = $frame;
}
} else {
$include = true;
}
if (! document_file($file, $include)) {
error("Error 404 - File Not Found");
}
if ($include) {
exit;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><?php print_string("documentation")?></title>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo current_charset(); ?>" />
</head>
<frameset rows="70,*">
<frame name="top" src="top.php" />
<frameset cols="200,*">
<frame name="contents" src="contents.php" />
<frame name="main" src="index.php?file=<?php echo "$file$sub"; ?>" />
</frameset>
</frameset>
</html>

View File

@ -1,421 +0,0 @@
<head>
<title>Moodle Docs: Installation</title>
<link rel="stylesheet" href="docstyles.css" type="TEXT/CSS">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF">
<h1>Installing Moodle</h1>
<blockquote>
<p>This guide explains how to install Moodle for the first time. It goes into some detail
about some of the steps, in order to cover the wide variety of small differences between
web server setups, so this document may look long and complicated. Don't be put off by this
- I usually set Moodle up in a few minutes!</p>
<p>Take your time and work through this document carefully - it will save you time later on.</p>
<p>Sections in this document:</p>
<ol>
<li><a href="#requirements">Requirements</a></li>
<li><a href="#downloading">Download</a></li>
<li><a href="#site">Site structure</a></li>
<li><a href="#data">Create a data directory</a></li>
<li><a href="#database">Create a database</a></li>
<li><a href="#webserver">Check web server settings</a></li>
<li><a href="#config">Edit config.php</a></li>
<li><a href="#admin">Go to the admin page</a></li>
<li><a href="#cron">Set up cron</a></li>
<li><a href="#course">Create a new course</a></li>
</ol>
<p>&nbsp;</p>
</blockquote>
<h3 class="sectionheading"><a name="requirements"></a>1. Requirements</h3>
<blockquote>
<p>Moodle is primarily developed in Linux using Apache, MySQL and PHP (also
sometimes known as the LAMP platform), but is also regularly tested with PostgreSQL
and on Windows XP, Mac OS X and Netware 6 operating systems</p>
<p>The requirements for Moodle are as follows:</p>
<ol>
<li>Web server software. Most people use <a href="http://www.apache.org/" target="_blank">Apache</a>,
but Moodle should work fine under any web server that supports PHP, such
as IIS on Windows platforms.</li>
<li><a href="http://www.php.net/" target="_blank">PHP</a> scripting language (version 4.1.0
or later), with the following settings:
<ul>
<li><a href="http://www.boutell.com/gd/" target="_blank">GD library</a>
turned ON, with support for JPG and PNG formats</li>
<li>zlib library turned ON (if you want to use backup/restore on Windows)</li>
<li>Sessions support turned ON</li>
<li>File uploading turned ON</li>
<li>Safe Mode must be turned OFF (see the forums on moodle.org for problems
caused by Safe Mode)</li>
</ul>
</li>
<li>a working database server: <a href="http://www.mysql.com/" target="_blank">MySQL</a>
or <a href="http://www.postgresql.org/" target="_blank">PostgreSQL</a> are
completely supported and recommended for use with Moodle 1.1. All other
databases will be supported fully in the next release.</li>
</ol>
<p>Most web hosts support all of this by default. If you are signed up with
one of the few webhosts that does not support these features ask them why,
and consider taking your business elsewhere.</p>
<p>If you want to run Moodle on your own computer and all this looks a bit daunting,
then please see our guide: <a href="http://moodle.org/doc/?file=installamp.html">Installing
Apache, MySQL and PHP</a>. It provides some step-by-step instructions to install
all this on most popular platforms.</p>
<p>&nbsp;</p>
</blockquote>
<h3 class="sectionheading"><a name="downloading"></a>2. Download</h3>
<blockquote>
<p>There are two ways to get Moodle, as a compressed package and via CVS. These
are explained in detail on the download page: <a href="http://moodle.org/download/" target="_blank">http://moodle.org/download/</a></p>
<p>After downloading and unpacking the archive, or checking out the files via
CVS, you will be left with a directory called &quot;moodle&quot;, containing
a number of files and folders. </p>
<p>You can either place the whole folder in your web server documents directory,
in which case the site will be located at <b>http://yourwebserver.com/moodle</b>,
or you can copy all the contents straight into the main web server documents
directory, in which case the site will be simply <b>http://yourwebserver.com</b>.</p>
</blockquote>
<p>&nbsp;</p>
<h3 class="sectionheading"><a name="site"></a>3. Site structure</h3>
<blockquote>
<p>Here is a quick summary of the contents of the Moodle folder, to help get
you oriented:</p>
<blockquote>
<p>config.php - the ONLY file you need to edit to get started<br />
version.php - defines the current version of Moodle code<br />
index.php - the front page of the site</p>
<ul>
<li>admin/ - code to administrate the whole server </li>
<li>auth/ - plugin modules to authenticate users </li>
<li>course/ - code to display and manage courses </li>
<li>doc/ - help documentation for Moodle (eg this page)</li>
<li>files/ - code to display and manage uploaded files</li>
<li>lang/ - texts in different languages, one directory per language </li>
<li>lib/ - libraries of core Moodle code </li>
<li>login/ - code to handle login and account creation </li>
<li>mod/ - all Moodle course modules</li>
<li>pix/ - generic site graphics</li>
<li>theme/ - theme packs/skins to change the look of the site.</li>
<li>user/ - code to display and manage users</li>
</ul>
<p>&nbsp;</p>
</blockquote>
</blockquote>
<h3 class="sectionheading"><a name="data"></a>4. Create a data directory</h3>
<blockquote>
<p>Moodle will also need some space on your hard disk to store uploaded files,
such as course documents and user pictures.</p>
<p>Create a directory for this purpose somewhere. For security, it's best that
this directory is NOT accessible directly via the web. The easiest way to do this
is to simply locate it OUTSIDE the web directory, otherwise protect it
by creating a file in the data directory called .htaccess, containing this line:
<blockquote>
<pre>deny from all<br />AllowOverride None</pre>
</blockquote>
<p>To make sure that Moodle can save uploaded files in this directory, check that
the web server software (eg Apache) has permission to write
to this directory. On Unix machines, this means setting the owner of the directory
to be something like &quot;nobody&quot; or &quot;apache&quot;.</p>
<p>On many shared hosting servers, you will probably need to restrict all file access
to your "group" (to prevent other webhost customers from looking at or changing your files),
but provide full read/write access to everyone else (which will allow the web server
to access your files). Speak to your server administrator if you are having
trouble setting this up securely.</p>
</blockquote>
<p>&nbsp;</p>
<h3 class="sectionheading"><a name="database"></a>5. Create a database</h3>
<blockquote>
<p>You need to create an empty database (eg "moodle") in your database system
along with a special user (eg "moodleuser") that has access to that database
(and that database only). You could use the "root" user if you wanted to, but
this is not recommended for a production system: if hackers manage to discover
the password then your whole database system would be at risk, rather than
just one database.
</p>
<p>Example command lines for MySQL: </p>
<pre>
# mysql -u root -p
> CREATE DATABASE moodle;
> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER ON moodle.*
TO moodleuser@localhost IDENTIFIED BY 'yourpassword';
> quit
# mysqladmin -p reload
</pre>
<p>Example command lines for PostgreSQL: </p>
<pre>
# su - postgres
> psql -c "create user moodleuser createdb;" template1
> psql -c "create database moodle;" -U moodleuser template1
> psql -c "alter user moodleuser nocreatedb;" template1
</pre>
<p>(For MySQL I highly recommend the use of <a href="http://phpmyadmin.sourceforge.net/">phpMyAdmin</a>
to manage your databases - you can do all this via a web interface).</p>
<p>As of version 1.0.8, Moodle now supports table prefixes, and so can safely share
a database with tables from other applications.</p>
</blockquote>
<p>&nbsp;</p>
<h3 class="sectionheading"><a name="webserver" id="webserver"></a>6. Check your web server settings</h3>
<blockquote>
<p>Firstly, make sure that your web server is set up to use index.php as a default
page (perhaps in addition to index.html, default.htm and so on).</p>
<p>In Apache, this is done using a DirectoryIndex parameter in your httpd.conf
file. Mine usually looks like this:</p>
<blockquote>
<pre><strong>DirectoryIndex</strong> index.php index.html index.htm </pre>
</blockquote>
<p>Just make sure index.php is in the list (and preferably towards the start
of the list, for efficiency).</p>
<p>Secondly, <b>if you are using Apache 2</b>, then you should turn on the <i>AcceptPathInfo</i>
variable, which allows scripts to be passed arguments like http://server/file.php/arg1/arg2.
This is essential to allow relative links between your resources, and also
provides a performance boost for people using your Moodle web site. You can
turn this on by adding these lines to your httpd.conf file.</p>
<blockquote>
<pre><strong>AcceptPathInfo</strong> on </pre>
</blockquote>
<p>Thirdly, Moodle requires a number of PHP settings to be active for it to
work. <b>On most servers these will already be the default settings.</b>
However, some PHP servers (and some of the more recent PHP versions) may
have things set differently. These are defined in PHP's configuration
file (usually called php.ini):</p>
<blockquote>
<pre>magic_quotes_gpc = 1 (preferred but not necessary)
magic_quotes_runtime = 0 (necessary)
file_uploads = 1
session.auto_start = 0
session.bug_compat_warn = 0
</pre>
</blockquote>
<p>If you don't have access to httpd.conf or php.ini on your server, or you
have Moodle on a server with other applications that require different settings,
then don't worry, you can still OVERRIDE all of the default settings.
<p>To do this, you need to create a file called <b>.htaccess</b> in Moodle's
main directory that contains definitions for these settings.
This only works on Apache servers and only when Overrides have been allowed.
<blockquote>
<pre>
DirectoryIndex index.php index.html index.htm
&lt;IfDefine APACHE2>
<b>AcceptPathInfo</b> on
&lt;/IfDefine>
php_flag magic_quotes_gpc 1
php_flag magic_quotes_runtime 0
php_flag file_uploads 1
php_flag session.auto_start 0
php_flag session.bug_compat_warn 0</pre>
</blockquote>
<p>You can also do things like define the maximum size for uploaded files:
<blockquote>
<pre>
LimitRequestBody 0
php_value upload_max_filesize 2M
php_value post_max_size 2M
</pre>
</blockquote>
<p>The easiest thing to do is just copy the sample file from lib/htaccess
and edit it to suit your needs. It contains further instructions. For
example, in a Unix shell:
<blockquote>
<pre>cp lib/htaccess .htaccess</pre>
</blockquote>
</blockquote>
<p>&nbsp;</p>
<h3 class="sectionheading"><a name="config"></a>7. Edit config.php</h3>
<blockquote>
<p>Now you can edit the configuration file, <strong>config.php</strong>, using a
text editor. This file is used by all other files in Moodle.</p>
<p>To start with, make a copy of <strong>config-dist.php</strong> and name it
config.php. We do this so that your config.php won't be overwritten in case
you upgrade Moodle later on. </p>
<p>Edit <strong>config.php</strong> to specify the database details that you
just defined (including a table prefix - notice that this is REQUIRED for
PostgreSQL), as well as the site address, file system directory and data directory.
The config file itself has detailed directions and examples.</p>
<p>Once you have done this the rest of the installation is via a web interface.
For the rest of this installation document we will assume your site is at:
<u>http://example.com/moodle</u></p>
</blockquote>
<p>&nbsp;</p>
<h3 class="sectionheading"><a name="admin"></a>8. Go to the admin page</h3>
<blockquote>
<p>The admin page should now be working at: <u>http://example.com/moodle/admin</u>.
If you try and access the front page of your site you'll be taken there automatically
anyway. The first time you access this admin page, you will be presented with
a GPL &quot;shrinkwrap&quot; agreement with which you must agree before you
can continue with the setup.</p>
<p>(Moodle will also try to set some cookies in your browser. If you have your
browser set up to let you choose to accept cookies, then you <b>must</b> accept
the Moodle cookies, or Moodle won't work properly.)
<p>Now Moodle will start setting up your database and creating tables to store
data. Firstly, the main database tables are created. You should see a number
of SQL statements followed by status messages (in green or red) that look
like this:</p>
<blockquote>
<p>CREATE TABLE course ( id int(10) unsigned NOT NULL auto_increment, category
int(10) unsigned NOT NULL default '0', password varchar(50) NOT NULL default
'', fullname varchar(254) NOT NULL default '', shortname varchar(15) NOT
NULL default '', summary text NOT NULL, format tinyint(4) NOT NULL default
'1', teacher varchar(100) NOT NULL default 'Teacher', startdate int(10)
unsigned NOT NULL default '0', enddate int(10) unsigned NOT NULL default
'0', timemodified int(10) unsigned NOT NULL default '0', PRIMARY KEY (id))
TYPE=MyISAM</p>
<p><font color="#006600">SUCCESS</font></p>
<p>...and so on, followed by: <font color="#006600">Main databases set up
successfully.</font> </p>
</blockquote>
<p>If you don't see these, then there must have been some problem with the database
or the configuration settings you defined in config.php. Check that PHP isn't
in a restricted "Safe Mode" (commercial web hosts sometimes have safe mode
turned on). You can check PHP variables by creating a little file containing
&lt? phpinfo() ?&gt and looking at it through a browser. Check all these and
try this page again.</p>
<p>Scroll down the very bottom of the page and press the &quot;Continue&quot;
link.</p>
<p>Next you will see a similar page that sets up all the tables required by
each Moodle module. As before, they should all be <font color="#006600">green</font>.</p>
<p>Scroll down the very bottom of the page and press the &quot;Continue&quot;
link.</p>
<p>You should now see a form where you can define more configuration variables
for your installation, such as the default language, SMTP hosts and so on.
Don't worry too much about getting everything right just now - you can always
come back and edit these later on using the admin interface. Scroll down to
the bottom and click &quot;Save changes&quot;.</p>
<p>If (and only if) you find yourself getting stuck on this page, unable to
continue, then your server probably has what I call the "buggy referrer" problem.
This is easy to fix: just turn off the &quot;secureforms&quot; setting, then
try to continue again.</p>
<p>The next page is a form where you can define parameters for your Moodle site
and the front page, such as the name, format, description and so on. Fill
this out (you can always come back and change these later) and then press
&quot;Save changes&quot;.</p>
<p>Finally, you will then be asked to create a top-level administration user
for future access to the admin pages. Fill out the details with your own name,
email etc and then click &quot;Save changes&quot;. Not all the fields are
required, but if you miss any important fields you'll be re-prompted for them.
</p>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<p><strong>Make sure you remember the username and password you chose
for the administration user account, as they will be necessary to
access the administration page in future.</strong></p>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
<p>(If for any reason your install is interrupted, or there is a system error
of some kind that prevents you from logging in using the admin account, you
can usually log in using the default username of &quot;<strong>admin</strong>&quot;,
with password &quot;<strong>admin</strong>&quot;.)</p>
<p>Once successful, you will be returned to home page of your site. Note the
administration links that appear down the left hand side of the page (these
items also appear on a separate Admin page) - these items are only visible
to you because you are logged in as the admin user. All your further administration
of Moodle can now be done using this menu, such as:</p>
<ul>
<li>creating and deleting courses</li>
<li>creating and editing user accounts</li>
<li>administering teacher accounts</li>
<li>changing site-wide settings like themes etc</li>
</ul>
</blockquote>
<p>&nbsp;</p>
<h3 class="sectionheading"><a name="cron"></a>9. Set up cron</h3>
<blockquote>
<p>Some of Moodle's modules require continual checks to perform tasks. For example,
Moodle needs to check the discussion forums so it can mail out copies of posts
to people who have subscribed.</p>
<p>The script that does all this is located in the admin directory, and is called
cron.php. However, it can not run itself, so you need to set up a mechanism
where this script is run regularly (eg every five or ten minutes). This provides
a &quot;heartbeat&quot; so that the script can perform functions at periods
defined by each module.</p>
<p>Note that the machine performing the cron <b>does not need to be the same
machine that is running Moodle</b>. For example, if you have a limited web
hosting service that does not have cron, then you can might choose to run
cron on another server or on your home computer. All that matters is that
the cron.php file is called regularly. </p>
<p>The load of this script is not very high, so 5 minutes is usually reasonable,
but if you're worried about it you can reduce the time period to something
like 15 minutes or even 30 minutes. It's best not to make the time period
too long, as delaying mail-outs can slow down activity within the course.</p>
<p>First, test that the script works by running it directly from your browser:</p>
<blockquote>
<pre>http://example.com/moodle/admin/cron.php</pre>
</blockquote>
<p>Now, you need to set up some of way of running the script automatically and
regularly. </p>
<h4> Running the script from a command line</h4>
<p>You can call the page from the command line just as you did in the example
above. For example, you can use a Unix utility like 'wget':</p>
<blockquote>
<pre>wget -q -O /dev/null http://example.com/moodle/admin/cron.php</pre>
</blockquote>
<p>Note in this example that the output is thrown away (to /dev/null).</p>
<p>The same thing using lynx:</p>
<blockquote>
<pre>lynx -dump http://example.com/moodle/admin/cron.php &gt; /dev/null</pre>
</blockquote>
<p>Alternatively you could use a standalone version of PHP, compiled to be run
on the command line. The advantage with doing this is that your web server
logs aren't filled with constant requests to cron.php. The disadvantage is
that you need to have access to a command-line version of php.</p>
<blockquote>
<pre>/opt/bin/php /web/moodle/admin/cron.php
(Windows) C:\apache\php\php.exe C:\apache\htdocs\moodle\admin\cron.php
</pre>
</blockquote>
<h4>Automatically running the script every 5 minutes</h4>
<p><b>On Unix systems</b>: Use <b>cron</b>. Edit your cron settings from the commandline
using &quot;crontab -e&quot; and add a line like:</p>
<blockquote>
<pre>*/5 * * * * wget -q -O /dev/null http://example.com/moodle/admin/cron.php</pre>
</blockquote>
<p>Usually, the "crontab" command will put you into the 'vi' editor. You enter
"insert mode" by pressing "i", then type in the line as above, then exit insert mode by
pressing ESC. You save and exit by typing ":wq", or quit without saving using ":q!" (without the quotes).</p>
<p><b>On Windows systems</b>: The simplest way is to use this little package <a href="http://moodle.org/download/moodle-cron-for-windows.zip" title="Click to download this package (150k)" target="_blank">moodle-cron-for-windows.zip</a>
which makes this whole thing very easy. You can also explore using the built-in
Windows feature for "Scheduled Tasks".</p>
<p>On web hosts: Your web-based control panel may have a web page that allows
you to set up this cron process. Ask your administrator for details on how
it works.</p>
<p></p>
</blockquote>
<h3 class="sectionheading"><a name="course"></a>10. Create a new course</h3>
<blockquote>
<p>Now that Moodle is running properly, you can create a course. </p>
<p>Select &quot;Create a new course&quot; from the Admin page (or the admin
links on the home page).</p>
<p>Fill out the form, paying special attention to the course format. You don't
have to worry about the details too much at this stage, as everything can
be changed later by the teacher.</p>
<p>Press &quot;Save changes&quot;, and you will be taken to a new form where
you can assign teachers to the course. You can only add existing user accounts
from this form - if you want to create a new teacher account then either ask
the teacher to create one for themselves (see the login page), or create one
for them using the &quot;Add a new user&quot; on the Admin page.</p>
<p>Once done, the course is ready to customise, and is accessible via the &quot;Courses&quot;
link on the home page.</p>
<p>See the &quot;<a href="./?file=teacher.html">Teacher Manual</a>&quot; for more details
on course-building.</p>
</blockquote>
<p>&nbsp;</p>
<p align="CENTER"><font size="1"><a href="." target="_top">Moodle Documentation</a></font></p>
<p align="CENTER"><font size="1">Version: $Id$</font></p>
</body>

View File

@ -1,24 +0,0 @@
<?PHP // $Id$
require("../config.php");
if ($CFG->forcelogin) {
require_login();
}
if (empty($CFG->langmenu)) {
$langmenu = "";
} else {
$currlang = current_language();
$langs = get_list_of_languages();
$langmenu = popup_form ("$CFG->wwwroot/doc/?lang=", $langs, "chooselang", $currlang, "", "", "", true, "parent");
}
if (! $site = get_site()) {
error("Site is misconfigured");
}
$strdocumentation = get_string("documentation");
print_header("$site->shortname: $strdocumentation", "$site->fullname", "$strdocumentation", "", "", true, $langmenu, navmenu($site, NULL, "parent"));
?>

View File

@ -1,40 +0,0 @@
<?PHP // $Id$
require("../config.php");
$id = optional_param('id',0,PARAM_INT); // course context
$file = required_param('file',PARAM_FILE); // file in this directory to view
$file = clean_filename($file);
if ($CFG->forcelogin) {
require_login();
}
if ($id) {
if (! $course = get_record("course", "id", $id)) {
error("Course is misconfigured");
}
$strhelp = get_string("help");
print_header("$course->shortname: $strhelp", "$course->fullname",
"<a href=\"../course/view.php?id=$course->id\">$course->shortname</a> -> $strhelp");
} else {
if (! $site = get_site()) {
error("Site is misconfigured");
}
$strdocumentation = get_string("documentation");
print_header("$site->shortname: $strhelp", "$site->fullname",
"<a href=\"view.php?file=contents.html\">$strdocumentation</a>");
}
echo "<blockquote>";
if (! document_file($file, true)) {
notify("404 - File Not Found");
}
echo "</blockquote>";
?>

View File

@ -1,18 +0,0 @@
<DBMIGRATION type="enrol/authorize" VERSION="2005120100">
<TABLES>
<TABLE name="enrol_authorize">
<FIELDS>
<FIELD name="ccname" method="NO_CONV" type="varchar" length="255" />
<FIELD name="transid" method="NO_CONV" type="varchar" length="255" />
<FIELD name="amount" method="NO_CONV" type="varchar" length="10" />
<FIELD name="currency" method="NO_CONV" type="char" length="3" />
<FIELD name="paymentmethod" method="NO_CONV" type="enum('cc', 'echeck')" length="0" default="cc"/>
</FIELDS>
</TABLE>
<TABLE name="enrol_authorize_refunds">
<FIELDS>
<FIELD name="amount" method="NO_CONV" type="varchar" length="10" />
</FIELDS>
</TABLE>
</TABLES>
</DBMIGRATION>

182
group/assign.php Normal file
View File

@ -0,0 +1,182 @@
<?php
/**
* Add/remove members from group.
*
* @copyright &copy; 2006 The Open University
* @author N.D.Freear AT open.ac.uk
* @author J.White AT open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package groups
*/
require_once('../config.php');
require_once('lib.php');
require_once($CFG->libdir.'/moodlelib.php');
$success = true;
$courseid = required_param('courseid', PARAM_INT);
$groupingid = required_param('grouping', PARAM_INT);
$groupid = required_param('group', PARAM_INT);
// Get the course information so we can print the header and
// check the course id is valid
$course = groups_get_course_info($courseid);
if (! $course) {
$success = false;
print_error('The course ID is invalid');
}
if ($success) {
// Make sure that the user has permissions to manage groups.
require_login($courseid);
$context = get_context_instance(CONTEXT_COURSE, $courseid);
if (! has_capability('moodle/course:managegroups', $context)) {
redirect();
}
if ($frm = data_submitted() and confirm_sesskey()) {
if (isset($frm->cancel)) {
redirect('index.php?id='. $courseid
.'&groupingid='. $groupingid .'&groupid='. $groupid);
}
elseif (isset($frm->add) and !empty($frm->addselect)) {
foreach ($frm->addselect as $userid) {
if (! $userid = clean_param($userid, PARAM_INT)) {
continue;
}
//echo "Try user $userid, group $groupid<br>\n";
$success = groups_add_member($groupid, $userid);
if (! $success) {
print_error('Failed to add user $userid to group.');
}
}
}
elseif (isset($frm->remove) and !empty($frm->removeselect)) {
foreach ($frm->removeselect as $userid) {
if (! $userid = clean_param($userid, PARAM_INT)) {
continue;
}
$success = groups_remove_member($groupid, $userid);
if (! $success) {
print_error('Failed to remove user $userid from group.');
}
}
}
}
// Print the page and form
$strgroups = get_string('groups');
$strparticipants = get_string('participants');
$groupname = groups_get_group_displayname($groupid);
print_header("$course->shortname: $strgroups",
"$course->fullname",
"<a href=\"$CFG->wwwroot/course/view.php?id=$courseid\">$course->shortname</a> ".
"-> <a href=\"$CFG->wwwroot/user/index.php?id=$courseid\">$strparticipants</a> ".
"-> $strgroups", '', '', true, '', user_login_string($course, $USER));
//require_once('assign-form.html');
?>
<div id="addmembersform">
<h3 class="main"><?php print_string('adduserstogroup', 'group'); echo " $groupname"; ?></h3>
<form name="assignform" id="assignform" method="post" action="">
<input type="hidden" name="sesskey" value="<?php p(sesskey()); ?>" />
<input type="hidden" name="courseid" value="<?php p($courseid); ?>" />
<input type="hidden" name="grouping" value="<?php echo $groupingid; ?>" />
<input type="hidden" name="group" value="<?php echo $groupid; ?>" />
<table summary="" align="center" cellpadding="5" cellspacing="0">
<tr>
<td valign="top">
<label for="removeselect"><?php print_string('existingusers', 'role'); //count($contextusers) ?></label>
<br />
<select name="removeselect[]" size="20" id="removeselect" multiple="multiple"
onfocus="document.assignform.add.disabled=true;
document.assignform.remove.disabled=false;
document.assignform.addselect.selectedIndex=-1;">
<?php
$userids = groups_get_members($groupid);
if ($userids != false) {
// Put the groupings into a hash and sorts them
foreach ($userids as $userid) {
$listmembers[$userid] = groups_get_user_displayname($userid, $courseid);
}
natcasesort($listmembers);
// Print out the HTML
foreach($listmembers as $id => $name) {
echo "<option value=\"$id\">$name</option>\n";
}
}
?>
</select></td>
<td valign="top">
<?php // Hidden assignment? ?>
<?php check_theme_arrows(); ?>
<p class="arrow_button">
<input name="add" id="add" type="submit" value="<?php echo '&nbsp;'.$THEME->larrow.' &nbsp; &nbsp; '.get_string('add'); ?>" title="<?php print_string('add'); ?>" />
<br />
<input name="remove" id="remove" type="submit" value="<?php echo '&nbsp; '.$THEME->rarrow.' &nbsp; &nbsp; '.get_string('remove'); ?>" title="<?php print_string('remove'); ?>" />
</p>
</td>
<td valign="top">
<label for="addselect"><?php print_string('potentialusers', 'role'); //$usercount ?></label>
<br />
<select name="addselect[]" size="20" id="addselect" multiple="multiple"
onfocus="document.assignform.add.disabled=false;
document.assignform.remove.disabled=true;
document.assignform.removeselect.selectedIndex=-1;">
<?php
$showall = 0;
unset($userids);
if ($showall == 0 && $groupingid != GROUP_NOT_IN_GROUPING) {
$userids = groups_get_users_not_in_any_group_in_grouping($courseid, $groupingid, $groupid);
} else {
$userids = groups_get_users_not_in_group($courseid, $groupid);
}
if ($userids != false) {
// Put the groupings into a hash and sorts them
foreach ($userids as $userid) {
$nonmembers[$userid] = groups_get_user_displayname($userid, $courseid);
}
natcasesort($nonmembers);
// Print out the HTML
foreach($nonmembers as $id => $name) {
echo "<option value=\"$id\">$name</option>\n";
}
}
?>
</select>
<br />
<?php //TODO: Search box
if (!empty($searchtext)) {
echo '<input name="showall" id="showall" type="submit" value="'.$strshowall.'" />'."\n";
}
?>
</td>
</tr>
<tr><td>
<input type="submit" name="cancel" value="<?php print_string('return', 'group'); ?>" />
</td></tr>
</table>
</form>
</div>
<?php
print_footer($course);
}
?>

View File

@ -2,7 +2,7 @@
/**
* Functions to make changes to groups in the database i.e. functions that
* access tables:
* groups_courses_groups, groups_groups and groups_groups_users.
* groups_courses_groups, groups and groups_members.
*
* @copyright &copy; 2006 The Open University
* @author J.White AT open.ac.uk
@ -10,7 +10,7 @@
* @package groups
*/
require_once($CFG->libdir.'/datalib.php');
require_once($CFG->dirroot.'/group/lib/lib.php');
require_once($CFG->dirroot.'/group/lib.php');
/*******************************************************************************
@ -73,7 +73,7 @@ function groups_db_get_members($groupid) {
if (!$groupid) {
$userids = false;
} else {
$users = get_records('groups_groups_users', 'groupid ', $groupid, '',
$users = get_records('groups_members', 'groupid ', $groupid, '',
$fields='id, userid');
if (!$users) {
$userids = false;
@ -98,13 +98,13 @@ function groups_db_get_members($groupid) {
*/
function groups_db_get_groups_for_user($userid, $courseid) {
if (!$userid or !$courseid) {
$groupid = false;
$groupids = false;
} else {
global $CFG;
$table_prefix = $CFG->prefix;
$sql = "SELECT g.id, userid
FROM {$table_prefix}groups_groups_users AS gm
INNER JOIN {$table_prefix}groups_groups AS g
FROM {$table_prefix}groups_members AS gm
INNER JOIN {$table_prefix}groups AS g
ON gm.groupid = g.id
INNER JOIN {$table_prefix}groups_courses_groups AS cg
ON g.id = cg.groupid
@ -131,19 +131,23 @@ function groups_db_get_groups_for_user($userid, $courseid) {
* Get the group settings object for a group - this contains the following
* properties:
* name, description, lang, theme, picture, hidepicture
* @param int $groupid The id of the gruop
* @param int $groupid The id of the group
* @param $courseid Optionally add the course ID, for backwards compatibility.
* @return object The group settings object
*/
function groups_db_get_group_settings($groupid) {
function groups_db_get_group_settings($groupid, $courseid=false) {
if (!$groupid) {
$groupsettings = false;
} else {
global $CFG;
$tableprefix = $CFG->prefix;
$sql = "SELECT id, name, description, lang, theme, picture, hidepicture
FROM {$tableprefix}groups_groups
FROM {$tableprefix}groups
WHERE id = $groupid";
$groupsettings = get_record_sql($sql);
if ($courseid && $groupsettings) {
$groupsettings->courseid = $courseid;
}
}
return $groupsettings;
@ -188,7 +192,7 @@ function groups_db_group_exists($groupid) {
if (!$groupid) {
$exists = false;
} else {
$exists = record_exists($table = 'groups_groups', 'id', $groupid);
$exists = record_exists($table = 'groups', 'id', $groupid);
}
return $exists;
@ -205,7 +209,7 @@ function groups_db_is_member($groupid, $userid) {
if (!$groupid or !$userid) {
$ismember = false;
} else {
$ismember = record_exists($table = 'groups_groups_users', 'groupid',
$ismember = record_exists($table = 'groups_members', 'groupid',
$groupid, 'userid', $userid);
}
@ -253,7 +257,7 @@ function groups_db_create_group($courseid, $groupsettings = false) {
$record->timecreated = time();
$record->timemodified = time();
//print_r($record);
$groupid = insert_record('groups_groups', $record);
$groupid = insert_record('groups', $record);
if ($groupid != false) {
$record2 = new Object();
@ -289,7 +293,7 @@ function groups_db_add_member($groupid, $userid) {
$record->groupid = $groupid;
$record->userid = $userid;
$record->timeadded = time();
$useradded = insert_record($table = 'groups_groups_users', $record);
$useradded = insert_record($table = 'groups_members', $record);
}
return $useradded;
@ -311,7 +315,7 @@ function groups_db_set_group_settings($groupid, $groupsettings) {
$record = $groupsettings;
$record->id = $groupid;
$record->timemodified = time();
$result = update_record('groups_groups', $record);
$result = update_record('groups', $record);
if (!$result) {
$success = false;
}
@ -336,7 +340,7 @@ function groups_db_remove_member($groupid, $userid) {
if (!$userid or !$groupid) {
$success = false;
} else {
$results = delete_records('groups_groups_users',
$results = delete_records('groups_members',
'groupid', $groupid, 'userid', $userid);
// delete_records returns an array of the results from the sql call,
// not a boolean, so we have to set our return variable
@ -392,7 +396,7 @@ function groups_db_delete_group($groupid) {
}
// Delete the group itself
$results = delete_records($table = 'groups_groups', $field1 = 'id',
$results = delete_records($table = 'groups', $field1 = 'id',
$value1 = $groupid);
// delete_records returns an array of the results from the sql call,
// not a boolean, so we have to set our return variable
@ -404,4 +408,57 @@ function groups_db_delete_group($groupid) {
return $success;
}
/**
* Internal function to set the time a group was modified.
*/
function groups_db_set_group_modified($groupid) {
return set_field('groups', 'timemodified', time(), 'id', $groupid);
}
/******************************************************************************
* Groups SQL clauses for modules and core.
*/
/**
* Returns the table in which group members are stored, with a prefix 'gm'.
* @return SQL string.
*/
function groups_members_from_sql() {
global $CFG;
return " {$CFG->prefix}groups_members gm ";
}
/**
* Returns a join testing user.id against member's user ID.
* Relies on 'user' table being included as 'user u'.
* Used in Quiz module reports.
* @param group ID, optional to include a test for this in the SQL.
* @return SQL string.
*/
function groups_members_join_sql($groupid=false) {
$sql = ' JOIN '.groups_members_from_sql().' ON u.id = gm.userid ';
if ($groupid) {
$sql = "AND gm.groupid = '$groupid' ";
}
return $sql;
//return ' INNER JOIN '.$CFG->prefix.'role_assignments ra ON u.id=ra.userid'.
// ' INNER JOIN '.$CFG->prefix.'context c ON ra.contextid=c.id AND c.contextlevel='.CONTEXT_GROUP.' AND c.instanceid='.$groupid;
}
/**
* Returns SQL for a WHERE clause testing the group ID.
* Optionally test the member's ID against another table's user ID column.
* @param groupid
* @param userid_sql Optional user ID column selector, example "mdl_user.id", or false.
* @return SQL string.
*/
function groups_members_where_sql($groupid, $userid_sql=false) {
$sql = " gm.groupid = '$groupid' ";
if ($userid_sql) {
$sql .= "AND $userid_sql = gm.userid ";
}
return $sql;
}
?>

View File

@ -24,12 +24,12 @@ require_once($CFG->libdir.'/datalib.php');
*/
function groups_db_get_groupings($courseid) {
if (!$courseid) {
$groupingid = false;
$groupingids = false;
} else {
$groupings = get_records('groups_courses_groupings', 'courseid ',
$courseid, '', $fields='id, groupingid');
if (!$groupings) {
$groupingsids = false;
$groupingids = false;
} else {
// Put the results into an array
$groupingids = array();
@ -217,7 +217,7 @@ function groups_db_grouping_exists($groupingid) {
$tableprefix = $CFG->prefix;
$sql = "SELECT gm.id
FROM {$tableprefix}groups_groupings_groups AS gg
INNER JOIN {$tableprefix}groups_groups_users AS gm
INNER JOIN {$tableprefix}groups_members AS gm
ON gg.groupid = gm.groupid
WHERE gm.userid = $userid AND gg.groupingid = $groupingid";
$belongstogroup = record_exists_sql($sql);

View File

@ -6,7 +6,7 @@
*
* @copyright &copy; 2006 The Open University
* @author J.White AT open.ac.uk
* @author N.D.Freear@open.ac.uk
* @author N.D.Freear AT open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package groups
*/
@ -96,15 +96,15 @@ function groups_create_database_tables() {
$creategroupingstablesql = "CREATE TABLE `{$CFG->prefix}groups_groupings` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(254) collate latin1_general_ci NOT NULL default '',
`description` text collate latin1_general_ci NOT NULL,
`timecreated` int(10) unsigned NOT NULL default '0',
`viewowngroup` binary(1) NOT NULL,
`viewallgroupsmembers` binary(1) NOT NULL,
`viewallgroupsactivities` binary(1) NOT NULL,
`teachersgroupmark` binary(1) NOT NULL,
`teachersgroupview` binary(1) NOT NULL,
`teachersoverride` binary(1) NOT NULL,
`name` varchar(254) collate latin1_general_ci NOT NULL,
`description` text collate latin1_general_ci NOT NULL default '',
`timecreated` int(10) unsigned NOT NULL default 0,
`viewowngroup` binary(1) NOT NULL default 1,
`viewallgroupsmembers` binary(1) NOT NULL default 0,
`viewallgroupsactivities` binary(1) NOT NULL default 0,
`teachersgroupmark` binary(1) NOT NULL default 0,
`teachersgroupview` binary(1) NOT NULL default 0,
`teachersoverride` binary(1) NOT NULL default 0,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ";
@ -132,7 +132,7 @@ function groups_create_database_tables() {
$creategroupstablesql = "CREATE TABLE {$CFG->prefix}groups_groups (
id SERIAL PRIMARY KEY,
name varchar(255) NOT NULL default '',
name varchar(255) NOT NULL,
description text NOT NULL default '',
enrolmentkey varchar(50) NOT NULL default '',
lang varchar(10) NOT NULL default 'en',
@ -165,15 +165,15 @@ function groups_create_database_tables() {
$creategroupingstablesql = "CREATE TABLE {$CFG->prefix}groups_groupings (
id SERIAL PRIMARY KEY,
name varchar(254) NOT NULL default '',
description text NOT NULL,
timecreated integer NOT NULL default '0',
viewowngroup integer NOT NULL,
viewallgroupsmembers integer NOT NULL,
viewallgroupsactivities integer NOT NULL,
teachersgroupmark integer NOT NULL,
teachersgroupview integer NOT NULL,
teachersoverride integer NOT NULL
name varchar(254) NOT NULL default,
description text NOT NULL default '',
timecreated integer NOT NULL default 0,
viewowngroup integer NOT NULL default 1,
viewallgroupsmembers integer NOT NULL default 0,
viewallgroupsactivities integer NOT NULL default 0,
teachersgroupmark integer NOT NULL default 0,
teachersgroupview integer NOT NULL default 0,
teachersoverride integer NOT NULL default 0
) ";
$creategroupingsgroupstablesql = "CREATE TABLE {$CFG->prefix}groups_groupings_groups (

96
group/db/install.xml Normal file
View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="group/db" VERSION="20061209" COMMENT="XMLDB file for Moodle groups."
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="groups" COMMENT="Each record represents a group." NEXT="groups_members">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="254" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="Short human readable unique name for the group." PREVIOUS="id" NEXT="description"/>
<FIELD NAME="description" TYPE="text" LENGTH="small" NOTNULL="true" DEFAULT="" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="enrolmentkey"/>
<FIELD NAME="enrolmentkey" TYPE="char" LENGTH="50" NOTNULL="true" DEFAULT="" SEQUENCE="false" ENUM="false" PREVIOUS="description" NEXT="lang"/>
<FIELD NAME="lang" TYPE="char" LENGTH="10" NOTNULL="true" DEFAULT="en" SEQUENCE="false" ENUM="false" PREVIOUS="enrolmentkey" NEXT="theme"/>
<FIELD NAME="theme" TYPE="char" LENGTH="50" NOTNULL="true" DEFAULT="" SEQUENCE="false" ENUM="false" PREVIOUS="lang" NEXT="picture"/>
<FIELD NAME="picture" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="theme" NEXT="hidepicture"/>
<FIELD NAME="hidepicture" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="picture" NEXT="timecreated"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="hidepicture" NEXT="timemodified"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="timecreated"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups"/>
</KEYS>
</TABLE>
<TABLE NAME="groups_members" COMMENT="Link a user to a group." PREVIOUS="groups" NEXT="groups_groupings">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="groupid"/>
<FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="userid"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupid" NEXT="timeadded"/>
<FIELD NAME="timeadded" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="userid"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_members"/>
</KEYS>
<INDEXES>
<INDEX NAME="groupid" UNIQUE="false" FIELDS="groupid" NEXT="userid"/>
<INDEX NAME="userid" UNIQUE="false" FIELDS="userid" PREVIOUS="groupid"/>
</INDEXES>
</TABLE>
<TABLE NAME="groups_groupings" COMMENT="A grouping is a collection of groups." PREVIOUS="groups_members" NEXT="groups_courses_groups">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="Short human readable unique name for group." PREVIOUS="id" NEXT="description"/>
<FIELD NAME="description" TYPE="text" LENGTH="small" NOTNULL="true" DEFAULT="" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="timecreated"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="description" NEXT="viewowngroup"/>
<FIELD NAME="viewowngroup" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="timecreated" NEXT="viewallgroupsmembers"/>
<FIELD NAME="viewallgroupsmembers" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="viewowngroup" NEXT="viewallgroupsactivities"/>
<FIELD NAME="viewallgroupsactivities" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="viewallgroupsmembers" NEXT="teachersgroupmark"/>
<FIELD NAME="teachersgroupmark" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="viewallgroupsactivities" NEXT="teachersgroupview"/>
<FIELD NAME="teachersgroupview" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="teachersgroupmark" NEXT="teachersoverride"/>
<FIELD NAME="teachersoverride" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="teachersgroupview" NEXT="teacherdeletable"/>
<FIELD NAME="teacherdeletable" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="teachersoverride"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_groupings"/>
</KEYS>
</TABLE>
<TABLE NAME="groups_courses_groups" COMMENT="Link a group to a course (or the site)." PREVIOUS="groups_groupings" NEXT="groups_courses_groupings">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="courseid"/>
<FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="groupid"/>
<FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="Default comment for the field, please edit me" PREVIOUS="courseid"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_courses_groups"/>
</KEYS>
</TABLE>
<TABLE NAME="groups_courses_groupings" COMMENT="Link a grouping to a course (or the site)." PREVIOUS="groups_courses_groups" NEXT="groups_groupings_groups">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="courseid"/>
<FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="groupingid"/>
<FIELD NAME="groupingid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="courseid"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_courses_groupings"/>
</KEYS>
</TABLE>
<TABLE NAME="groups_groupings_groups" COMMENT="Link a group to a grouping." PREVIOUS="groups_courses_groupings">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="groupingid"/>
<FIELD NAME="groupingid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="groupid"/>
<FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="groupingid" NEXT="timeadded"/>
<FIELD NAME="timeadded" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupid"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_groupings_groups"/>
</KEYS>
</TABLE>
</TABLES>
<STATEMENTS>
<STATEMENT NAME="insert log_display" TYPE="insert" TABLE="log_display" COMMENT="Initial insert of records on table log_display">
<SENTENCES>
<SENTENCE TEXT="(module, action, mtable, field) VALUES ('group', 'view', 'groups', 'name')" />
</SENTENCES>
</STATEMENT>
</STATEMENTS>
</XMLDB>

View File

@ -19,7 +19,7 @@
CREATE TABLE `prefix_groups_courses_groupings` (
`id` int(10) unsigned NOT NULL auto_increment,
`courseid` int(10) unsigned NOT NULL default '0',
`groupingid` mediumint(9) NOT NULL,
`groupingid` mediumint(9) NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `courseid` (`courseid`)
@ -34,7 +34,7 @@ CREATE TABLE `prefix_groups_courses_groupings` (
CREATE TABLE `prefix_groups_courses_groups` (
`id` int(10) unsigned NOT NULL auto_increment,
`courseid` int(10) unsigned NOT NULL default '0',
`groupid` int(11) NOT NULL,
`groupid` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `courseid` (`courseid`)
@ -48,16 +48,16 @@ CREATE TABLE `prefix_groups_courses_groups` (
CREATE TABLE `prefix_groups_groupings` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(254) character set latin1 collate latin1_general_ci NOT NULL default '',
`description` text character set latin1 collate latin1_general_ci NOT NULL,
`name` varchar(254) NOT NULL,
`description` text NOT NULL default '',
`timecreated` int(10) unsigned NOT NULL default '0',
`viewowngroup` tinyint(1) NOT NULL,
`viewallgroupsmembers` tinyint(1) NOT NULL,
`viewallgroupsactivities` tinyint(1) NOT NULL,
`teachersgroupmark` tinyint(1) NOT NULL,
`teachersgroupview` binary(1) NOT NULL,
`teachersoverride` binary(1) NOT NULL,
`teacherdeletable` binary(1) NOT NULL,
`viewowngroup` tinyint(1) NOT NULL default 1,
`viewallgroupsmembers` tinyint(1) NOT NULL default 0,
`viewallgroupsactivities` tinyint(1) NOT NULL default 0,
`teachersgroupmark` tinyint(1) NOT NULL default 0,
`teachersgroupview` binary(1) NOT NULL default 0,
`teachersoverride` binary(1) NOT NULL default 0,
`teacherdeletable` binary(1) NOT NULL default 0,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM ;
@ -71,7 +71,7 @@ CREATE TABLE `prefix_groups_groupings` (
CREATE TABLE `prefix_groups_groupings_groups` (
`id` int(10) unsigned NOT NULL auto_increment,
`groupingid` int(10) unsigned default '0',
`groupid` int(10) NOT NULL,
`groupid` int(10) NOT NULL default '0',
`timeadded` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
@ -81,16 +81,16 @@ CREATE TABLE `prefix_groups_groupings_groups` (
# --------------------------------------------------------
#
# Table structure for table `prefix_groups_groups`
# Table structure for table `prefix_groups`
#
CREATE TABLE `prefix_groups_groups` (
CREATE TABLE `prefix_groups` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(254) character set latin1 collate latin1_general_ci NOT NULL default '',
`description` text character set latin1 collate latin1_general_ci NOT NULL,
`enrolmentkey` varchar(50) character set latin1 collate latin1_general_ci NOT NULL default '',
`lang` varchar(10) character set latin1 collate latin1_general_ci NOT NULL default 'en',
`theme` varchar(50) character set latin1 collate latin1_general_ci NOT NULL default '',
`name` varchar(255) NOT NULL,
`description` text NOT NULL default '',
`enrolmentkey` varchar(50) NOT NULL default '',
`lang` varchar(10) NOT NULL default 'en',
`theme` varchar(50) NOT NULL default '',
`picture` int(10) unsigned NOT NULL default '0',
`hidepicture` int(1) unsigned NOT NULL default '0',
`timecreated` int(10) unsigned NOT NULL default '0',
@ -102,10 +102,10 @@ CREATE TABLE `prefix_groups_groups` (
# --------------------------------------------------------
#
# Table structure for table `prefix_groups_groups_users`
# Table structure for table `prefix_groups_members`
#
CREATE TABLE `prefix_groups_groups_users` (
CREATE TABLE `prefix_groups_members` (
`id` int(10) unsigned NOT NULL auto_increment,
`groupid` int(10) unsigned NOT NULL default '0',
`userid` int(10) unsigned NOT NULL default '0',

View File

@ -1,59 +1,65 @@
CREATE TABLE prefix_groups_courses_groups (
id SERIAL PRIMARY KEY,
courseid integer NOT NULL default '0',
groupid integer NOT NULL default '0'
);
CREATE INDEX prefix_groups_courses_groups_courseid_idx ON prefix_groups_courses_groups (courseid);
CREATE TABLE prefix_groups_groups (
id SERIAL PRIMARY KEY,
name varchar(255) NOT NULL default '',
description text NOT NULL default '',
enrolmentkey varchar(50) NOT NULL default '',
lang varchar(10) NOT NULL default 'en',
theme varchar(50) NOT NULL default '',
picture integer NOT NULL default '0',
hidepicture integer NOT NULL default '0',
timecreated integer NOT NULL default '0',
timemodified integer NOT NULL default '0'
);
CREATE TABLE prefix_groups_groups_users (
id SERIAL PRIMARY KEY,
groupid integer NOT NULL default '0',
userid integer NOT NULL default '0',
timeadded integer NOT NULL default '0'
);
CREATE INDEX prefix_groups_groups_users_groupid_idx ON prefix_groups_groups_users (groupid);
CREATE INDEX prefix_groups_groups_users_userid_idx ON prefix_groups_groups_users (userid);
COMMENT ON TABLE prefix_groups_groups_users IS 'New groupings (OU).';
CREATE TABLE prefix_groups_courses_groupings (
id SERIAL PRIMARY KEY,
courseid integer NOT NULL default '0',
groupingid integer NOT NULL
);
id SERIAL PRIMARY KEY,
courseid integer NOT NULL default 0,
groupingid integer NOT NULL default 0
);
CREATE INDEX prefix_groups_courses_groupings_courseid_idx ON prefix_groups_courses_groupings (courseid);
COMMENT ON TABLE prefix_groups_courses_groupings IS 'New groupings (OU).';
CREATE TABLE prefix_groups_courses_groups (
id SERIAL PRIMARY KEY,
courseid integer NOT NULL default '0',
groupid integer NOT NULL default '0'
);
CREATE INDEX prefix_groups_courses_groups_courseid_idx ON prefix_groups_courses_groups (courseid);
CREATE TABLE prefix_groups_groupings (
id SERIAL PRIMARY KEY,
name varchar(254) NOT NULL default '',
description text NOT NULL,
timecreated integer NOT NULL default '0',
viewowngroup integer NOT NULL,
viewallgroupsmembers integer NOT NULL,
viewallgroupsactivities integer NOT NULL,
teachersgroupmark integer NOT NULL,
teachersgroupview integer NOT NULL,
teachersoverride integer NOT NULL
);
id SERIAL PRIMARY KEY,
name varchar(254) NOT NULL,
description text NOT NULL default '',
timecreated integer NOT NULL default 0,
viewowngroup integer NOT NULL default 1,
viewallgroupsmembers integer NOT NULL default 0,
viewallgroupsactivities integer NOT NULL default 0,
teachersgroupmark integer NOT NULL default 0,
teachersgroupview integer NOT NULL default 0,
teachersoverride integer NOT NULL default 0
);
CREATE TABLE prefix_groups_groupings_groups (
id SERIAL PRIMARY KEY,
groupingid integer default '0',
groupid integer NOT NULL,
timeadded integer NOT NULL default '0'
);
id SERIAL PRIMARY KEY,
groupingid integer NOT NULL default 0,
groupid integer NOT NULL default 0,
timeadded integer NOT NULL default 0
);
CREATE INDEX prefix_groups_groupings_groups_groupingid_idx ON prefix_groups_groupings_groups (groupingid);
CREATE TABLE prefix_groups (
id SERIAL PRIMARY KEY,
name varchar(255) NOT NULL,
description text NOT NULL default '',
enrolmentkey varchar(50) NOT NULL default '',
lang varchar(10) NOT NULL default 'en',
theme varchar(50) NOT NULL default '',
picture integer NOT NULL default '0',
hidepicture integer NOT NULL default '0',
timecreated integer NOT NULL default '0',
timemodified integer NOT NULL default '0'
);
CREATE TABLE prefix_groups_members (
id SERIAL PRIMARY KEY,
groupid integer NOT NULL default '0',
userid integer NOT NULL default '0',
timeadded integer NOT NULL default '0'
);
CREATE INDEX prefix_groups_members_groupid_idx ON prefix_groups_members (groupid);
CREATE INDEX prefix_groups_members_userid_idx ON prefix_groups_members (userid);
COMMENT ON TABLE prefix_groups_members IS 'New groupings (OU).';

223
group/db/upgrade.php Normal file
View File

@ -0,0 +1,223 @@
<?php //$Id: upgrade.php,v 1.2 2007/01/03 04:55:20 moodler Exp $
// This file keeps track of upgrades to
// groups
//
// Sometimes, changes between versions involve
// alterations to database structures and other
// major things that may break installations.
//
// The upgrade function in this file will attempt
// to perform all the necessary actions to upgrade
// your older installtion to the current version.
//
// If there's something it cannot do itself, it
// will tell you what you need to do.
//
// The commands in here will all be database-neutral,
// using the functions defined in lib/ddllib.php
function upgrade_group_db($continueto) {
/// This function upgrades the group tables, if necessary
/// It's called from admin/index.php.
global $CFG, $db;
$group_version = ''; // Get code versions
require_once ("$CFG->dirroot/group/version.php");
if (empty($CFG->group_version)) { // New groups have never been installed...
$status = false;
$strdatabaseupgrades = get_string('databaseupgrades');
print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades, '',
'<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
false, "&nbsp;", "&nbsp;");
upgrade_log_start();
print_heading('group');
$db->debug=true;
//TODO: for testing, revert to 'old' groups.
if (! get_config('group_version')) {
$status = revert_group_db();
}
//... But Moodle is already installed.
if (table_exists($t_groups = new XMLDBTable('groups'))) {
$status = rename_table($t_groups, 'groups_temp');
$status = rename_table(new XMLDBTable('groups_members'), 'groups_members_temp');
}
/// Both old .sql files and new install.xml are supported
/// but we prioritize install.xml (XMLDB) if present
if (file_exists($CFG->dirroot . '/group/db/install.xml')) {
$status = install_from_xmldb_file($CFG->dirroot . '/group/db/install.xml'); //New method
} else if (file_exists($CFG->dirroot . '/group/db/' . $CFG->dbtype . '.sql')) {
$status = modify_database($CFG->dirroot . '/group/db/' . $CFG->dbtype . '.sql'); //Old method
}
$status = transfer_group_db();
$db->debug = false;
if (set_config('group_version', $group_version)) { //and set_config('group_release', $group_release)) {
//initialize default group settings now
$adminroot = admin_get_root();
apply_default_settings($adminroot->locate('groups'));
notify(get_string('databasesuccess'), 'green');
notify(get_string('databaseupgradegroups', '', $group_version), 'green');
print_continue($continueto);
exit;
} else {
error("Upgrade of group system failed! (Could not update version in config table)");
}
}
/// Upgrading code starts here
$oldupgrade = false;
$newupgrade = false;
if (is_readable($CFG->dirroot . '/group/db/' . $CFG->dbtype . '.php')) {
include_once($CFG->dirroot . '/group/db/' . $CFG->dbtype . '.php'); // defines old upgrading function
$oldupgrade = true;
}
if (is_readable($CFG->dirroot . '/group/db/upgrade.php')) {
include_once($CFG->dirroot . '/group/db/upgrade.php'); // defines new upgrading function
$newupgrade = true;
}
if ($group_version > $CFG->group_version) { // Upgrade tables
$strdatabaseupgrades = get_string('databaseupgrades');
print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades, '',
'<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>');
upgrade_log_start();
print_heading('group');
/// Run de old and new upgrade functions for the module
$oldupgrade_function = 'group_upgrade';
$newupgrade_function = 'xmldb_group_upgrade';
/// First, the old function if exists
$oldupgrade_status = true;
if ($oldupgrade && function_exists($oldupgrade_function)) {
$db->debug = true;
$oldupgrade_status = $oldupgrade_function($CFG->group_version);
} else if ($oldupgrade) {
notify ('Upgrade function ' . $oldupgrade_function . ' was not available in ' .
'/group/db/' . $CFG->dbtype . '.php');
}
/// Then, the new function if exists and the old one was ok
$newupgrade_status = true;
if ($newupgrade && function_exists($newupgrade_function) && $oldupgrade_status) {
$db->debug = true;
$newupgrade_status = $newupgrade_function($CFG->group_version);
} else if ($newupgrade) {
notify ('Upgrade function ' . $newupgrade_function . ' was not available in ' .
'/group/db/upgrade.php');
}
$db->debug=false;
/// Now analyze upgrade results
if ($oldupgrade_status && $newupgrade_status) { // No upgrading failed
if (set_config('group_version', $group_version)) { //and set_config('group_release', $group_release))
notify(get_string('databasesuccess'), 'green');
notify(get_string('databaseupgradegroups', '', $group_version), 'green');
print_continue($continueto);
exit;
} else {
error("Upgrade of group system failed! (Could not update version in config table)");
}
} else {
error("Upgrade failed! See group/version.php");
}
upgrade_log_finish();
print_footer();
} else if ($group_version < $CFG->group_version) {
upgrade_log_start();
notify("WARNING!!! The code you are using is OLDER than the version that made these databases!");
upgrade_log_finish();
print_footer();
}
}
function transfer_group_db() {
$status = true;
if (table_exists($t_groups = new XMLDBTable('groups_temp'))) {
$status = (bool)$groups_r = get_records('groups_temp');
$status = (bool)$members_r= get_records('groups_members_temp');
if (! $groups_r) {
return $status;
}
foreach ($groups_r as $group) {
if (debugging()) {
print_object($group);
}
$group->enrolmentkey = $group->password;
///unset($group->password);
///unset($group->courseid);
$status = (bool)$newgroupid = groups_create_group($group->courseid, $group);
if ($members_r) {
foreach ($members_r as $member) {
if ($member->groupid == $group->id) {
$status = groups_add_member($newgroupid, $member->userid);
}
}
}
echo 'Status: '.$status;
}
///$status = drop_table($t_groups);
///$status = drop_table(new XMLDBTable('groups_members_temp'));
}
return $status;
}
/**
* For testing, it's useful to be able to revert to 'old' groups.
*/
function revert_group_db() {
$status = false;
//$status = (bool)$rs = delete_records('config', 'name', 'group_version');
if (!get_config('group_version') && table_exists(new XMLDBTable('groups_groupings'))) { //debugging()
$status = drop_table(new XMLDBTable('groups'));
$status = drop_table(new XMLDBTable('groups_members'));
$status = drop_table(new XMLDBTable('groups_groupings'));
$status = drop_table(new XMLDBTable('groups_courses_groups'));
$status = drop_table(new XMLDBTable('groups_courses_groupings'));
$status = drop_table(new XMLDBTable('groups_groupings_groups'));
$status = rename_table(new XMLDBTable('groups_temp'), 'groups');
$status = rename_table(new XMLDBTable('groups_members_temp'), 'groups_members');
}
return $status;
}
function xmldb_group_upgrade($oldversion=0) {
//global $CFG, $THEME, $db;
$result = true;
/// And upgrade begins here. For each one, you'll need one
/// block of code similar to the next one. Please, delete
/// this comment lines once this file start handling proper
/// upgrade code.
/// if ($result && $oldversion < YYYYMMDD00) { //New version in version.php
/// $result = result of "/lib/ddllib.php" function calls
/// }
return $result;
}
?>

208
group/group.php Normal file
View File

@ -0,0 +1,208 @@
<?php
/**
* Create group OR edit group settings.
*
* @copyright &copy; 2006 The Open University
* @author N.D.Freear AT open.ac.uk
* @author J.White AT open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package groups
*/
require_once('../config.php');
require_once('lib.php');
require_once($CFG->libdir.'/moodlelib.php');
require_once($CFG->libdir.'/uploadlib.php');
$success = true;
$err = array();
$courseid = required_param('courseid', PARAM_INT);
$groupingid = optional_param('grouping', false, PARAM_INT);
$groupid = optional_param('group', false, PARAM_INT);
$groupsettings->name = optional_param('name', PARAM_ALPHANUM);
$groupsettings->description= optional_param('description', PARAM_ALPHANUM);
$groupsettings->enrolmentkey= optional_param('enrolmentkey', PARAM_ALPHANUM);
$groupsettings->hidepicture= optional_param('hidepicture', PARAM_BOOL);
$delete = optional_param('delete', false, PARAM_BOOL);
// Get the course information so we can print the header and
// check the course id is valid
$course = groups_get_course_info($courseid);
if (! $course) {
$success = false;
print_error('The course ID is invalid');
}
if ($success) {
// Make sure that the user has permissions to manage groups.
require_login($courseid);
$context = get_context_instance(CONTEXT_COURSE, $courseid);
if (! has_capability('moodle/course:managegroups', $context)) {
redirect();
}
/// If data submitted, then process and store.
if ($frm = data_submitted() and confirm_sesskey()) {
if (isset($frm->cancel)) {
redirect(groups_home_url($courseid, $groupid, $groupingid, false));
}
elseif (isset($frm->confirmdelete)) {
///TODO:
}
elseif (empty($frm->name)) {
$err['name'] = get_string('missingname');
}
elseif (isset($frm->update)) {
if (GROUP_NOT_IN_GROUPING == $groupingid) {
print_error('errornotingrouping', 'group', groups_home_url($courseid), get_string('notingrouping', 'group'));
}
if (! $groupid) {
$success = (bool)$groupid = groups_create_group($courseid); //$groupsettings);
$success = groups_add_group_to_grouping($groupid, $groupingid);
}
if ($success) {
//require_once($CFG->dirroot.'/lib/uploadlib.php');
$um = new upload_manager('imagefile',false,false,null,false,0,true,true);
if ($um->preprocess_files()) {
require_once("$CFG->libdir/gdlib.php");
if (save_profile_image($groupid, $um, 'groups')) {
$groupsettings->picture = 1;
}
}
$success = (bool)groups_set_group_settings($groupid, $groupsettings);
}
if ($success) {
redirect(groups_home_url($courseid, $groupid, $groupingid, false));
}
else {
print_error('Error creating/updating group.');
}
}
}
/// OR, prepare the form.
if ($groupid) {
// Form to edit existing group.
$group = groups_get_group_settings($groupid);
if (! $group) {
print_error('The group ID is invalid.');
}
$strname = s($group->name);
$strdesc = s($group->description);
$strbutton = get_string('save', 'group');
$strheading = get_string('editgroupsettings', 'group');
} else {
// Form to create a new one.
$strname = get_string('defaultgroupname', 'group');
$strdesc = '';
$strbutton = $strheading = get_string('creategroup', 'group');
}
$strgroups = get_string('groups');
$strparticipants = get_string('participants');
if ($delete) {
$strheading = get_string('deleteselectedgroup', 'group');
} //else { $strheader = get_string('groupinfoedit'); }
$maxbytes = get_max_upload_file_size($CFG->maxbytes, $course->maxbytes);
if (!empty($CFG->gdversion) and $maxbytes) {
$printuploadpicture = true;
} else {
$printuploadpicture = false;
}
/// Print the page and form
print_header("$course->shortname: ". $strheading,
"$course->fullname",
"<a href=\"$CFG->wwwroot/course/view.php?id=$courseid\">$course->shortname</a> ".
"-> <a href=\"$CFG->wwwroot/user/index.php?id=$courseid\">$strparticipants</a> ".
"-> $strgroups", '', '', true, '', user_login_string($course, $USER));
$usehtmleditor = false;
?>
<h3 class="main"><?php echo $strheading ?></h3>
<form action="group.php" method="post" class="mform notmform" id="groupform">
<input type="hidden" name="sesskey" value="<?php p(sesskey()); ?>" />
<input type="hidden" name="courseid" value="<?php p($courseid); ?>" />
<input type="hidden" name="grouping" value="<?php p($groupingid); ?>" />
<?php
if ($groupid) {
echo '<input type="hidden" name="group" value="'. $groupid .'" />';
}
if ($delete) {
/*echo 'Are you sure you want to delete group X ?';
choose_from_menu_yesno('confirmdelete', false, '', true);*/
?>
<p>Are you sure you want to delete group '<?php p($strname) ?>'?</p>
<input type="hidden" name="delete" value="1" />
<input type="submit" name="confirmdelete" value="Yes" />
<input type="submit" name="cancel" value="<?php print_string('cancel', 'group'); ?>" />
<?php
} else {
?>
<div class="fitem">
<p><label for="groupname"><?php
print_string('groupname', 'group');
if (isset($err['name'])) {
echo' ';
formerr($err['name']);
} ?>&nbsp; </label></p>
<p class="felement"><input id="groupname" name="name" type="text" size="40" value="<?php echo $strname; ?>" /></p>
</div>
<p><label for="edit-description"><?php print_string('groupdescription', 'group'); ?>&nbsp;</label></p>
<p><?php print_textarea($usehtmleditor, 5, 45, 200, 400, 'description', $strdesc); ?></p>
<p><label for="enrolmentkey"><?php print_string('enrolmentkey', 'group'); ?>&nbsp;</label></p>
<p><input id="enrolmentkey" name="enrolmentkey" type="text" size="25" /></p>
<?php if ($printuploadpicture) { ?>
<p><label for="menuhidepicture"><?php print_string('hidepicture', 'group'); ?>&nbsp;</label></p>
<p><?php $options = array();
$options[0] = get_string('no');
$options[1] = get_string('yes');
choose_from_menu($options, 'hidepicture', isset($group)? $group->hidepicture: 1, '');?></p>
<p><label ><?php /* for="groupicon" */ print_string('newpicture', 'group');
helpbutton('picture', get_string('helppicture'));
print_string('maxsize', '', display_size($maxbytes), 'group');
if (isset($err['imagefile'])) formerr($err['imagefile']);
?>&nbsp;</label></p>
<p><?php upload_print_form_fragment(1, array('groupicon'), null,false,null,0,0,false); ?></p>
<?php
}
?>
<p class="fitem">
<label for="id_submit">&nbsp;</label>
<span class="f--element fsubmit">
<input type="submit" name="update" id="id_submit" value="<?php echo $strbutton; ?>" />
<input type="submit" name="cancel" value="<?php print_string('cancel', 'group'); ?>" />
</span>
</p>
<?php } //IF($delete) ?>
<span class="clearer">&nbsp;</span>
</form>
<?php
print_footer($course);
}
?>

132
group/grouping.php Normal file
View File

@ -0,0 +1,132 @@
<?php
/**
* Create grouping OR edit grouping settings.
*
* @copyright &copy; 2006 The Open University
* @author N.D.Freear AT open.ac.uk
* @author J.White AT open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package groups
*/
require_once('../config.php');
require_once('lib.php');
require_once($CFG->libdir.'/moodlelib.php');
$success = true;
$courseid = required_param('courseid', PARAM_INT);
$groupingid = optional_param('grouping', false, PARAM_INT);
$groupingsettings->name = optional_param('name', PARAM_ALPHANUM);
$groupingsettings->description= optional_param('description', PARAM_ALPHANUM);
// Get the course information so we can print the header and
// check the course id is valid
$course = groups_get_course_info($courseid);
if (! $course) {
$success = false;
print_error('The course ID is invalid');
}
if ($success) {
// Make sure that the user has permissions to manage groups.
require_login($courseid);
$context = get_context_instance(CONTEXT_COURSE, $courseid);
if (! has_capability('moodle/course:managegroups', $context)) {
redirect();
}
/// If data submitted, then process and store.
if ($frm = data_submitted() and confirm_sesskey()) {
if (isset($frm->cancel)) {
redirect(groups_home_url($courseid, null, $groupingid, false));
}
elseif (empty($frm->name)) {
$err['name'] = get_string('missingname');
}
elseif (isset($frm->update)) {
if ($groupingid) {
$success = (bool)groups_set_grouping_settings($groupingid, $groupingsettings);
}
else {
$success = (bool)$groupingid = groups_create_grouping($courseid, $groupingsettings);
}
if ($success) {
redirect(groups_home_url($courseid, null, $groupingid, false));
}
else {
print_error('Error creating/updating grouping.');
}
}
}
/// OR, prepare the form.
if ($groupingid) {
// Form to edit existing grouping.
$grouping = groups_get_grouping_settings($groupingid);
if (! $grouping) {
print_error('errorinvalidgrouping', 'group', groups_home_url($courseid));
}
$strname = s($grouping->name);
$strdesc = s($grouping->description);
$strbutton = get_string('save', 'group');
$strheading = get_string('editgroupingsettings', 'group');
} else {
// Form to create a new one.
$strname = get_string('defaultgroupingname', 'group');
$strdesc = '';
$strbutton = $strheading = get_string('creategrouping', 'group');
}
$strgroups = get_string('groups');
$strparticipants = get_string('participants');
/// Print the page and form
print_header("$course->shortname: $strgroups",
"$course->fullname",
"<a href=\"$CFG->wwwroot/course/view.php?id=$courseid\">$course->shortname</a> ".
"-> <a href=\"$CFG->wwwroot/user/index.php?id=$courseid\">$strparticipants</a> ".
"-> $strgroups", '', '', true, '', user_login_string($course, $USER));
$usehtmleditor = false;
?>
<h3 class="main"><?php echo $strheading ?></h3>
<form action="grouping.php" method="post" class="mform notmform" id="groupingform">
<input type="hidden" name="sesskey" value="<?php p(sesskey()); ?>" />
<input type="hidden" name="courseid" value="<?php p($courseid); ?>" />
<?php
if ($groupingid) {
echo '<input type="hidden" name="grouping" value="'. $groupingid .'" />';
}
?>
<div class="f-item">
<p><label for="groupingname"><?php print_string('groupingname', 'group'); ?>&nbsp;</label></p>
<p><input id="groupingname" name="name" type="text" size="40" value="<?php echo $strname; ?>" /></p>
</div>
<p><label for="edit-description"><?php print_string('groupingdescription', 'group'); ?>&nbsp;</label></p>
<p><?php print_textarea($usehtmleditor, 5, 45, 200, 400, 'description', $strdesc); ?></p>
<p class="fitem">
<label for="id_submit">&nbsp;</label>
<span class="f-element fsubmit">
<input type="submit" name="update" id="id_submit" value="<?php echo $strbutton; ?>" />
<input type="submit" name="cancel" value="<?php print_string('cancel', 'group'); ?>" />
</span>
</p>
<span class="clearer">&nbsp;</span>
</form>
<?php
print_footer($course);
}
?>

View File

@ -1,56 +0,0 @@
<?php
/**
* Functions required for setting up the database to use the new groups.
*
* @copyright &copy; 2006 The Open University
* @author J.White AT open.ac.uk
* @author N.D.Freear@open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package groups
*/
require_once('../config.php');
require_once($CFG->dirroot.'/group/db/dbsetup.php');
require_once($CFG->dirroot.'/group/lib/utillib.php');
// Set up the database
groups_create_database_tables();
// Change database tables - course table need to remove two fields add groupingid field
// Move everything over
// Course module instance need to add groupingid field
// Module table - add group support field.
// Add deletable by teacher field.
/**
* Copies the moodle groups to a new grouping within IMS groups
* @param int $courseid The id of the course
* @return int The id of the grouping to which the groups have been copied, or false if an error occurred.
*/
function groups_copy_moodle_groups_to_groups($courseid) {
$groupingsettings = new Object();
$groupingsettings->name = 'Old moodle groups';
$groupingid = groups_create_grouping($courseid, $groupingsettings);
$groupids = groups_get_moodle_groups($courseid);
if (!$groupids) {
$groupingid = false;
} else {
foreach($groupids as $groupid) {
$groupcopied = groups_db_copy_moodle_group_to_imsgroup($groupid, $courseid);
if (!$groupcopied) {
$groupingid = false;
}
$groupadded = groups_add_group_to_grouping($groupid, $groupingid);
if (!$groupadded) {
$groupingid = false;
}
}
}
return $groupingid;
}
?>

View File

@ -1,199 +0,0 @@
-- phpMyAdmin SQL Dump
-- version 2.8.1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Oct 24, 2006 at 05:23 PM
-- Server version: 5.0.21
-- PHP Version: 4.4.2-pl1
--
-- Database: `moodle`
--
-- --------------------------------------------------------
--
-- Table structure for table `mdl_course`
--
CREATE TABLE `mdl_course` (
`id` int(10) unsigned NOT NULL auto_increment,
`category` int(10) unsigned NOT NULL default '0',
`sortorder` int(10) unsigned NOT NULL default '0',
`password` varchar(50) collate utf8_unicode_ci NOT NULL default '',
`fullname` varchar(254) collate utf8_unicode_ci NOT NULL default '',
`shortname` varchar(100) collate utf8_unicode_ci NOT NULL default '',
`idnumber` varchar(100) collate utf8_unicode_ci NOT NULL default '',
`summary` text collate utf8_unicode_ci NOT NULL,
`format` varchar(10) collate utf8_unicode_ci NOT NULL default 'topics',
`showgrades` smallint(2) unsigned NOT NULL default '1',
`modinfo` longtext collate utf8_unicode_ci NOT NULL,
`newsitems` smallint(5) unsigned NOT NULL default '1',
`teacher` varchar(100) collate utf8_unicode_ci NOT NULL default 'Teacher',
`teachers` varchar(100) collate utf8_unicode_ci NOT NULL default 'Teachers',
`student` varchar(100) collate utf8_unicode_ci NOT NULL default 'Student',
`students` varchar(100) collate utf8_unicode_ci NOT NULL default 'Students',
`guest` tinyint(2) unsigned NOT NULL default '0',
`startdate` int(10) unsigned NOT NULL default '0',
`enrolperiod` int(10) unsigned NOT NULL default '0',
`numsections` smallint(5) unsigned NOT NULL default '1',
`marker` int(10) unsigned NOT NULL default '0',
`maxbytes` int(10) unsigned NOT NULL default '0',
`showreports` int(4) unsigned NOT NULL default '0',
`visible` int(1) unsigned NOT NULL default '1',
`hiddensections` int(2) unsigned NOT NULL default '0',
`groupmode` int(4) unsigned NOT NULL default '0',
`groupmodeforce` int(4) unsigned NOT NULL default '0',
`lang` varchar(10) collate utf8_unicode_ci NOT NULL default '',
`theme` varchar(50) collate utf8_unicode_ci NOT NULL default '',
`cost` varchar(10) collate utf8_unicode_ci NOT NULL default '',
`currency` char(3) collate utf8_unicode_ci NOT NULL default 'USD',
`timecreated` int(10) unsigned NOT NULL default '0',
`timemodified` int(10) unsigned NOT NULL default '0',
`metacourse` int(1) unsigned NOT NULL default '0',
`requested` int(1) unsigned NOT NULL default '0',
`restrictmodules` int(1) unsigned NOT NULL default '0',
`expirynotify` tinyint(1) unsigned NOT NULL default '0',
`expirythreshold` int(10) unsigned NOT NULL default '0',
`notifystudents` tinyint(1) unsigned NOT NULL default '0',
`enrollable` tinyint(1) unsigned NOT NULL default '1',
`enrolstartdate` int(10) unsigned NOT NULL default '0',
`enrolenddate` int(10) unsigned NOT NULL default '0',
`enrol` varchar(20) collate utf8_unicode_ci NOT NULL default '',
PRIMARY KEY (`id`),
KEY `category` (`category`),
KEY `idnumber` (`idnumber`),
KEY `shortname` (`shortname`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=7 ;
-- --------------------------------------------------------
--
-- Table structure for table `mdl_course_modules`
--
CREATE TABLE `mdl_course_modules` (
`id` int(10) unsigned NOT NULL auto_increment,
`course` int(10) unsigned NOT NULL default '0',
`module` int(10) unsigned NOT NULL default '0',
`instance` int(10) unsigned NOT NULL default '0',
`section` int(10) unsigned NOT NULL default '0',
`added` int(10) unsigned NOT NULL default '0',
`score` tinyint(4) NOT NULL default '0',
`indent` int(5) unsigned NOT NULL default '0',
`visible` tinyint(1) NOT NULL default '1',
`visibleold` tinyint(1) NOT NULL default '1',
`groupingid` int(10) NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `visible` (`visible`),
KEY `course` (`course`),
KEY `module` (`module`),
KEY `instance` (`instance`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2 ;
-- --------------------------------------------------------
--
-- Table structure for table `mdl_groups_courses_groupings`
--
CREATE TABLE `mdl_groups_courses_groupings` (
`id` int(10) unsigned NOT NULL auto_increment,
`courseid` int(10) unsigned NOT NULL default '0',
`groupingid` mediumint(9) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `courseid` (`courseid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=87 ;
-- --------------------------------------------------------
--
-- Table structure for table `mdl_groups_courses_groups`
--
CREATE TABLE `mdl_groups_courses_groups` (
`id` int(10) unsigned NOT NULL auto_increment,
`courseid` int(10) unsigned NOT NULL default '0',
`groupid` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `courseid` (`courseid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=132 ;
-- --------------------------------------------------------
--
-- Table structure for table `mdl_groups_groupings`
--
CREATE TABLE `mdl_groups_groupings` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(254) character set latin1 collate latin1_general_ci NOT NULL default '',
`description` text character set latin1 collate latin1_general_ci NOT NULL,
`timecreated` int(10) unsigned NOT NULL default '0',
`viewowngroup` tinyint(1) NOT NULL,
`viewallgroupsmembers` tinyint(1) NOT NULL,
`viewallgroupsactivities` tinyint(1) NOT NULL,
`teachersgroupmark` tinyint(1) NOT NULL,
`teachersgroupview` binary(1) NOT NULL,
`teachersoverride` binary(1) NOT NULL,
`teacherdeletable` binary(1) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=87 ;
-- --------------------------------------------------------
--
-- Table structure for table `mdl_groups_groupings_groups`
--
CREATE TABLE `mdl_groups_groupings_groups` (
`id` int(10) unsigned NOT NULL auto_increment,
`groupingid` int(10) unsigned default '0',
`groupid` int(10) NOT NULL,
`timecreated` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `courseid` (`groupingid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=67 ;
-- --------------------------------------------------------
--
-- Table structure for table `mdl_groups_groups`
--
CREATE TABLE `mdl_groups_groups` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(254) character set latin1 collate latin1_general_ci NOT NULL default '',
`description` text character set latin1 collate latin1_general_ci NOT NULL,
`enrolmentkey` varchar(50) character set latin1 collate latin1_general_ci NOT NULL default '',
`lang` varchar(10) character set latin1 collate latin1_general_ci NOT NULL default 'en',
`theme` varchar(50) character set latin1 collate latin1_general_ci NOT NULL default '',
`picture` int(10) unsigned NOT NULL default '0',
`hidepicture` int(1) unsigned NOT NULL default '0',
`timecreated` int(10) unsigned NOT NULL default '0',
`timemodified` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=132 ;
-- --------------------------------------------------------
--
-- Table structure for table `mdl_groups_groups_users`
--
CREATE TABLE `mdl_groups_groups_users` (
`id` int(10) unsigned NOT NULL auto_increment,
`groupid` int(10) unsigned NOT NULL default '0',
`userid` int(10) unsigned NOT NULL default '0',
`timeadded` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `groupid` (`groupid`),
KEY `userid` (`userid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=175 ;

21
group/lib.php Normal file
View File

@ -0,0 +1,21 @@
<?php
/**
* Library including new groups and groupings.
*
* @copyright &copy; 2006 The Open University
* @author J.White AT open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package groups
*/
require_once($CFG->dirroot.'/group/lib/basicgrouplib.php');
require_once($CFG->dirroot.'/group/lib/groupinglib.php');
require_once($CFG->dirroot.'/group/lib/utillib.php');
require_once($CFG->dirroot.'/group/lib/automaticgroupinglib.php');
require_once($CFG->dirroot.'/group/lib/legacylib.php');
?>

View File

@ -28,10 +28,10 @@ require_once($CFG->dirroot.'/group/db/dbbasicgrouplib.php');
*****************************/
/**
* Gets a list of the group ids for a specified course id
* @param int $courseid The id of the course.
* @return array | false Returns an array of the userids or false if no records
* or an error occurred.
* Gets a list of the group IDs for a specified course.
* @param int $courseid The id of the course.
* @return array | false Returns an array of the group IDs or false if no records
* or an error occurred.
*/
function groups_get_groups($courseid) {
$groupids = groups_db_get_groups($courseid);
@ -50,6 +50,7 @@ function groups_get_groups($courseid) {
*/
function groups_get_members($groupid, $membertype = false) {
$userids = groups_db_get_members($groupid);
return $userids;
}
@ -67,6 +68,19 @@ function groups_get_groups_for_user($userid, $courseid) {
return $groupids;
}
function groups_get_all_groups_for_user($userid) {
$groups = get_records('groups_members', 'userid', $userid);
if (! $groups) {
return false;
}
// Put the results into an array
$groupids = array();
foreach ($groups as $group) {
array_push($groupids, $group->id);
}
return $groupids;
}
/**
* Gets the groups for the current user and specified course
* @param int $courseid The id of the course
@ -89,8 +103,8 @@ function groups_get_groups_for_current_user($courseid) {
* @param int $groupid The id of the gruop
* @return object The group settings object
*/
function groups_get_group_settings($groupid) {
return groups_db_get_group_settings($groupid);
function groups_get_group_settings($groupid, $courseid=false) {
return groups_db_get_group_settings($groupid, $courseid);
}
/**
@ -100,8 +114,8 @@ function groups_get_group_settings($groupid) {
* @return string The path of the image for the group
*/
function groups_get_group_image_path($groupid) {
$image = ''; //TODO: ??
return $CFG->dataroot.'/groups/'.$groupid.'/'.$image;
//TODO: groupid=1, /user/pixgroup.php/1/f1.jpg ??
return $CFG->wwwroot.'/pixgroup.php/'.$groupid.'/f1.jpg';
}
/**
@ -111,7 +125,10 @@ function groups_get_group_image_path($groupid) {
*/
function groups_get_group_name($groupid) {
$settings = groups_get_group_settings($groupid);
return $settings->name;
if ($settings) {
return $settings->name;
}
return false;
}
/**
@ -168,8 +185,9 @@ function groups_group_exists($groupid) {
* @return boolean True if the user is a member of the group, false otherwise
*/
function groups_is_member($groupid, $userid) {
$ismember = groups_db_is_member($groupid, $userid);
return $ismember;
$ismember = groups_db_is_member($groupid, $userid);
return $ismember;
}
@ -254,7 +272,7 @@ function groups_create_group($courseid, $groupsettings = false) {
* @return boolean True if info was added successfully, false otherwise.
*/
function groups_set_group_settings($groupid, $groupsettings) {
return groups_db_set_group_settings($groupid, $groupsettings);
return groups_db_set_group_settings($groupid, $groupsettings);
}
@ -277,7 +295,9 @@ function groups_add_member($groupid, $userid) {
} else {
$useradded = groups_db_add_member($groupid, $userid);
}
if ($useradded) {
$useradded = groups_db_set_group_modified($groupid);
}
return $useradded;
}
@ -294,11 +314,22 @@ function groups_add_member($groupid, $userid) {
* See comment above on web service autoupdating.
*/
function groups_delete_group($groupid) {
$groupdeleted = groups_db_delete_group($groupid);
$groupdeleted = groups_db_delete_group($groupid);
return $groupdeleted;
}
/*function groups_delete_groups($groupids) {
if (! $groupids) {
return false;
}
$success = true;
foreach ($groupids as $id) {
$success = $success && groups_db_delete_group($id);
}
return $success;
}*/
/**
* Deletes the specified user from the specified group
@ -308,7 +339,29 @@ function groups_delete_group($groupid) {
* See comment above on web service autoupdating.
*/
function groups_remove_member($groupid, $userid) {
return groups_db_remove_member($groupid, $userid);
$success = groups_db_remove_member($groupid, $userid);
if ($success) {
$success = groups_db_set_group_modified($groupid);
}
return $success;
}
function groups_remove_all_members($groupid) {
if (! groups_group_exists($groupid)) {
//Woops, delete group last!
return false;
}
$userids = groups_get_members($groupid);
if (! $userids) {
return false;
}
$success = true;
foreach ($userids as $id) {
$success = $success && groups_db_remove_member($groupid, $id);
}
$success = $success && groups_db_set_group_modified($groupid);
return $success;
}
?>

View File

@ -12,6 +12,7 @@
require_once($CFG->dirroot.'/group/lib/basicgrouplib.php');
require_once($CFG->dirroot.'/group/db/dbgroupinglib.php');
define('GROUP_NOT_IN_GROUPING', -1);
/*****************************
Access/List functions
@ -73,7 +74,7 @@ function groups_get_groups_for_user_in_grouping($userid, $groupingid) {
}
/**
* Gets a list of the groups not a specified grouping
* Gets a list of the groups not in a specified grouping
* @param int $groupingid The grouping specified
* @return array An array of the group ids
*/
@ -88,6 +89,33 @@ function groups_get_groups_not_in_grouping($groupingid, $courseid) {
return $groupids;
}
/**
* TODO: move to dbgroupinglib.php
*/
function groups_get_groups_not_in_any_grouping($courseid) {
global $CFG;
/* SELECT g.id
FROM headmdl_groups AS g
WHERE g.id NOT IN
(SELECT groupid FROM headmdl_groups_groupings_groups);
*/
$sql = "SELECT g.id
FROM {$CFG->prefix}groups AS g
WHERE g.id NOT IN
(SELECT groupid FROM {$CFG->prefix}groups_groupings_groups)";
$records = get_records_sql($sql);
$groupids = array();
if ($records) {
foreach ($records as $r) {
$groupids[] = $r->id;
}
} else {
return false;
}
return $groupids;
}
/**
* Gets the users for the course who are not in any group of a grouping.
* @param int $courseid The id of the course
@ -101,19 +129,18 @@ function groups_get_users_not_in_any_group_in_grouping($courseid, $groupingid,
$users = get_course_users($courseid);
$userids = groups_users_to_userids($users);
$nongroupmembers = array();
if ($userids) {
foreach($userids as $userid) {
if (!groups_is_member_of_some_group_in_grouping($userid,
$groupingid)) {
// If a group has been specified don't include members of that
// group
if ($groupid and !groups_is_member($userid, $groupid)) {
array_push($nongroupmembers, $userid);
} else {
array_push($nongroupmembers, $userid);
}
}
}
if (! $userids) {
return $nongroupmembers;
}
foreach($userids as $userid) {
if (!groups_is_member_of_some_group_in_grouping($userid, $groupingid)) {
// If a group has been specified don't include members of that group
if ($groupid and !groups_is_member($userid, $groupid)) {
array_push($nongroupmembers, $userid);
} else {
///array_push($nongroupmembers, $userid);
}
}
}
return $nongroupmembers;
}
@ -282,7 +309,10 @@ function groups_create_grouping($courseid, $groupingsettings = false) {
* doesn't belong to the same course as the grouping.
*/
function groups_add_group_to_grouping($groupid, $groupingid) {
$belongstogrouping = groups_belongs_to_grouping($groupid, $groupingid);
if (GROUP_NOT_IN_GROUPING == $groupingid) {
return false;
}
$belongstogrouping = groups_belongs_to_grouping($groupid, $groupingid);
if (!groups_grouping_exists($groupingid)) {
$groupadded = false;
} elseif (!$belongstogrouping) {

View File

@ -1,9 +1,13 @@
<?php
/**
* Legacy groups functions - these were in moodlelib.php.
* Legacy groups functions - these were in moodlelib.php, datalib.php, weblib.php
*
* @@@ Don't look at this file - still tons to do!
*
* TODO: For the moment these functions are in /lib/deprecatedlib.php
* get_group_students
* get_group_teachers
*
* @copyright &copy; 2006 The Open University
* @author J.White AT open.ac.uk and others
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
@ -18,10 +22,20 @@
* This is needed to support upload of users into the database
* @param int $courseid The id of the course
* @param string $groupname
* @return int $groupname
* @return int $groupid
*/
function groups_get_group_by_name($courseid, $groupname) {
// TO DO
//uploaduser.php, get_record("groups","courseid",$course[$i]->id,"name",$addgroup[$i])
$groupids = groups_db_get_groups($courseid);
if (! $groupids) {
return false;
}
foreach ($groupids as $id) {
if (groups_get_group_name($id) == $groupname) {
return $id;
}
}
return false;
}
/**
@ -41,8 +55,8 @@ function get_groups($courseid, $userid=0) {
} else {
$groupids = groups_get_groups($courseid);
}
return groups_groupids_to_groups($groupids);
return groups_groupids_to_groups($groupids, $courseid);
}
@ -110,68 +124,6 @@ function get_group_users($groupid, $sort='u.lastaccess DESC', $exceptions='',
/**
* Returns an array of user objects
*
* @uses $CFG
* @param int $groupid The group(s) in question.
* @param string $sort How to sort the results
* @return object (changed to groupids)
*/
function get_group_students($groupids, $sort='u.lastaccess DESC') {
global $CFG;
if (is_array($groupids)){
$groups = $groupids;
$groupstr = '(m.groupid = '.array_shift($groups);
foreach ($groups as $index => $value){
$groupstr .= ' OR m.groupid = '.$value;
}
$groupstr .= ')';
}
else {
$groupstr = 'm.groupid = '.$groupids;
}
return get_records_sql("SELECT DISTINCT u.*
FROM {$CFG->prefix}user u,
{$CFG->prefix}groups_members m,
{$CFG->prefix}groups g,
{$CFG->prefix}user_students s
WHERE $groupstr
AND m.userid = u.id
AND m.groupid = g.id
AND g.courseid = s.course
AND s.userid = u.id
ORDER BY $sort");
}
/**
* Returns list of all the teachers who can access a group
*
* @uses $CFG
* @param int $courseid The course in question.
* @param int $groupid The group in question.
* @return object
*/
function get_group_teachers($courseid, $groupid) {
/// Returns a list of all the teachers who can access a group
if ($teachers = get_course_teachers($courseid)) {
foreach ($teachers as $key => $teacher) {
if ($teacher->editall) { // These can access anything
continue;
}
if (($teacher->authority > 0) and ismember($groupid, $teacher->id))
{ // Specific group teachers
continue;
}
unset($teachers[$key]);
}
}
return $teachers;
}
/**
* Add a user to a group, return true upon success or if user already a group
@ -187,18 +139,17 @@ function add_user_to_group($groupid, $userid) {
/**
* Get the group ID of the current user in the given course
* Get the IDs for the user's groups in the given course.
*
* @uses $USER
* @param int $courseid The course being examined - relates to id field in
* 'course' table.
* @return array An array of the groupids that the user belongs to.
* @param int $courseid The course being examined - the 'course' table id field.
* @return array An _array_ of groupids.
* (Was return $groupids[0] - consequences!)
*/
function mygroupid($courseid) {
global $USER;
// TODO: check whether needs to be groups or groupids.
$groupids = groups_get_groups_for_user($USER->id, $courseid);
return $groupids[0];
return $groupids;
}
/**
@ -207,12 +158,17 @@ function mygroupid($courseid) {
*/
function groupmode($course, $cm=null) {
if ($cm and !$course->groupingid) {
if ($cm and !$course->groupmodeforce) {
return $cm->groupmode;
}
return $course->groupmode;
/*if ($cm and !$course->groupingid) {
//TODO: was $coursemodule
return groups_has_groups_setup_for_instance($cm);
} else {
return groups_has_groups_setup($course->id);
}
}*/
}
@ -245,15 +201,20 @@ function set_current_group($courseid, $groupid) {
*/
function get_current_group($courseid, $full = false) {
global $SESSION;
$mygroupid = mygroupid($courseid);
if (is_array($mygroupid)) {
$mygroupid = array_shift($mygroupid);
}
if (isset($SESSION->currentgroup[$courseid])) {
$currentgroup = $SESSION->currentgroup[$courseid];
} else {
$currentgroup = mygroupid($courseid);
$currentgroup = $mygroupid;
}
if ($currentgroup) {
$SESSION->currentgroup[$courseid] = mygroupid($courseid);
$SESSION->currentgroup[$courseid] = $mygroupid;
}
if ($full) {
@ -294,19 +255,19 @@ function get_and_set_current_group($course, $groupmode, $groupid=-1) {
$context = get_context_instance(CONTEXT_COURSE, $course->id);
if ($groupid) { // Try to change the current group to this groupid
if ($group = get_record('groups', 'id', $groupid, 'courseid', $course->id)) { // Exists
if (groups_group_belongs_to_course($groupid, $course->id)) { // Exists TODO:check.
if (has_capability('moodle/site:accessallgroups', $context)) { // Sets current default group
$currentgroupid = set_current_group($course->id, $group->id);
$currentgroupid = set_current_group($course->id, $groupid);
} elseif ($groupmode == VISIBLEGROUPS) {
// All groups are visible
//if (ismember($group->id)){
$currentgroupid = set_current_group($course->id, $group->id); //set this since he might post
$currentgroupid = set_current_group($course->id, $groupid); //set this since he might post
/*)}else {
$currentgroupid = $group->id;*/
} elseif ($groupmode == SEPARATEGROUPS) { // student in separate groups switching
if (ismember($group->id)) { //check if is a member
$currentgroupid = set_current_group($course->id, $group->id); //might need to set_current_group?
$currentgroupid = set_current_group($course->id, $groupid); //might need to set_current_group?
}
else {
echo($group->id);
@ -362,7 +323,7 @@ function setup_and_print_groups($course, $groupmode, $urlroot) {
groups_instance_print_grouping_selector();
}//added code here to allow non-editting teacher to swap in-between his own groups
//added code for students in separategrous to swtich groups
else if ($groupmode == SEPARATEGROUPS and (isteacher($course->id) or isstudent($course->id))) {
else if ($groupmode == SEPARATEGROUPS and has_capability('moodle/course:view', $context)) {
groups_instance_print_group_selector();
}
@ -370,6 +331,14 @@ function setup_and_print_groups($course, $groupmode, $urlroot) {
}
function groups_instance_print_grouping_selector() {
//TODO: ??
}
function groups_instance_print_group_selector() {
//TODO: ??
}
function oldgroups_print_user_group_info($currentgroup, $isseparategroups, $courseid) {
global $CFG;
$context = get_context_instance(CONTEXT_COURSE, $courseid);
@ -394,4 +363,50 @@ function oldgroups_print_user_group_info($currentgroup, $isseparategroups, $cour
}
}
/**
* Get the group object, including the course ID by default.
* @param groupid ID of the group.
* @param getcourse (default true), include the course ID in the return.
* @return group object, optionally including 'courseid'.
*/
function groups_get_group($groupid, $getcourse=true) {
$group = groups_db_get_group_settings($groupid);
if ($group && $getcourse) {
$group->courseid = groups_get_course($groupid);
}
return $group;
}
/**
* Get an array of groups, as id => name.
* Replaces, get_records_menu("groups", "courseid", $course->id, "name ASC", "id,name")
* (For /user/index.php)
*/
function groups_get_groups_names($courseid) {
$groupids = groups_db_get_groups($courseid);
if (! $groupids) {
return false;
}
$groups_names = array();
foreach ($groupids as $id) {
$groups_names[$id] = groups_get_group_name($id);
}
//TODO: sort. SQL?
return $groups_names;
}
/**
* Get the groups that a number of users are in.
* (For block_quiz_results.php)
*/
function groups_get_groups_users($userids, $courseid) {
global $CFG;
$groups_users = get_records_sql(
'SELECT gm.userid, gm.groupid, g.name FROM '.$CFG->prefix.'groups g LEFT JOIN '.$CFG->prefix.'groups_members gm ON g.id = gm.groupid '.
'WHERE g.courseid = '.$courseid.' AND gm.userid IN ('.implode(',', $userids).')'
);
return $groups_users;
}
?>

View File

@ -106,6 +106,9 @@ function groups_get_group_displayname($groupid) {
* @return string The display name of the grouping
*/
function groups_get_grouping_displayname($groupingid) {
if (GROUP_NOT_IN_GROUPING == $groupingid) {
return get_string('notingrouping', 'group');
}
$groupingsettings = groups_get_grouping_settings($groupingid);
if ($groupingsettings) {
$groupingname = $groupingsettings->name;
@ -152,8 +155,19 @@ function groups_groups_to_groupids($groups) {
function groups_groupid_to_group($groupid) {
}
// @@@ TO DO
function groups_groupids_to_groups($groupids) {
/**
* Given an array of group IDs get an array of group objects.
* TODO: quick and dirty. Replace with SQL?
*/
function groups_groupids_to_groups($groupids, $courseid=false) {
if (! $groupids) {
return false;
}
$groups = array();
foreach ($groupids as $id) {
$groups[] = groups_get_group_settings($id, $courseid);
}
return $groups;
}
@ -196,4 +210,68 @@ function groups_get_course($groupid) {
return false;
}
/**
* Return the address for the group settings page.
* (For /user/index.php etc.)
* @param $courseid
* @param $groupid
* @param $groupingid Optional grouping ID
* @param $html True for HTML pages, eg. on error. False for HTTP redirects.
* @param $param Extra parameters.
*/
function groups_group_edit_url($courseid, $groupid, $groupingid=false, $html=true, $param=false) {
global $CFG;
$html ? $sep = '&amp;' : $sep = '&';
$url = $CFG->wwwroot.'/group/group.php?courseid='.$courseid;
if ($groupid) {
$url .= $sep.'group='.$groupid;
}
if ($groupingid) {
$url .= $sep.'grouping='.$groupingid;
}
if ($param) {
$url .= $sep.$param;
}
return $url;
}
/** Internal use only. */
function groups_grouping_edit_url($courseid, $groupingid=false, $html=true) {
global $CFG;
$html ? $sep = '&amp;' : $sep = '&';
$url = $CFG->wwwroot.'/group/grouping.php?courseid='.$courseid;
if ($groupingid) {
$url .= $sep.'grouping='.$groupingid;
}
return $url;
}
/** Internal use only. */
function groups_members_add_url($courseid, $groupid, $groupingid=false, $html=true) {
global $CFG;
$html ? $sep = '&amp;' : $sep = '&';
$url = $CFG->wwwroot.'/group/assign.php?courseid='.$courseid.$sep.'group='.$groupid;
if ($groupingid) {
$url .= $sep.'grouping='.$groupingid;
}
return $url;
}
/**
* Return the address for the main group management page.
* (For admin block.)
*/
function groups_home_url($courseid, $groupid=false, $groupingid=false, $html=true) {
global $CFG;
$html ? $sep = '&amp;' : $sep = '&';
$url = $CFG->wwwroot.'/group/index.php?id='.$courseid;
if ($groupid) {
$url .= $sep.'group='.$groupid;
}
if ($groupingid) {
$url .= $sep.'grouping='.$groupingid;
}
return $url;
}
?>

View File

@ -5,7 +5,7 @@
* /admin/report/simpletest/index.php?showpasses=1&showsearch=1&path=course%2Fgroups
*
* @copyright &copy; 2006 The Open University
* @author N.D.Freear@open.ac.uk
* @author N.D.Freear AT open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package groups
*
@ -25,6 +25,12 @@ class basicgrouplib_test extends UnitTestCase {
var $userid_2= 0;
var $groupid = 0;
function __construct() {
parent::UnitTestCase();
groups_create_role();
}
function test_get_user() {
$this->assertTrue($user = groups_get_user(2)); //Primary admin.
if (isset($user)) {
@ -53,6 +59,7 @@ class basicgrouplib_test extends UnitTestCase {
$groupinfo->name = 'Group '. $this->getLabel(); //'Temporary Group Name'
$this->assertTrue(groups_set_group_settings($this->groupid, $groupinfo));
$this->assertTrue($groupinfo->name == groups_get_group_name($this->groupid));
$this->assertTrue($this->courseid == groups_get_course($this->groupid));
}
function test_add_member() {

View File

@ -3,7 +3,7 @@
* Unit tests for new Moodle Groups - groupinglib.php
*
* @copyright &copy; 2006 The Open University
* @author N.D.Freear@open.ac.uk
* @author N.D.Freear AT open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package groups
*/

11
group/version.php Normal file
View File

@ -0,0 +1,11 @@
<?php
////////////////////////////////////////////////////////////////////////////////
// Code fragment to define the group version etc.
// This fragment is called by /admin/index.php
////////////////////////////////////////////////////////////////////////////////
$group_version = 2006120401;
//$module->requires = 2006120400; // Requires this Moodle version
?>

View File

@ -1,4 +1,18 @@
<?php
/**
* Language strings for new Moodle Groups (cvs:/group/)
*
* @copyright &copy; 2006 The Open University
* @author J.White AT open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package groups
*/
$string['groupmember'] = 'Group Member';
$string['groupmemberdesc'] = 'Standard role for a member of a group.';
$string['notingrouping'] = '[Not in a grouping]';
$string['errornotingrouping'] = 'Sorry, you can\'t create a group in $a';
$string['groupings'] = 'Groupings';
$string['grouping'] = 'Grouping';
@ -22,7 +36,7 @@ $string['addexistinggroupstogrouping'] = 'Add existing groups to grouping';
$string['addgroupstogrouping'] = 'Add groups to grouping';
$string['removeselectedusers'] = 'Remove selected users';
$string['adduserstogroup'] = 'Add users to group';
$string['adduserstogroup'] = 'Add/remove users from group'; //'Add users to group';
$string['groupingname'] = 'Grouping name';
$string['defaultgroupingname'] = 'Grouping';
@ -52,9 +66,9 @@ $string['displaygrouping'] = 'Display grouping';
$string['addgroupstogrouping'] = 'Add groups to grouping';
$string['showusersalreadyingroup'] = 'Show users already in a group in the grouping';
$string ['save'] = 'Save';
$string['save'] = 'Save';
$string['cancel'] = 'Cancel';
$string['return'] = 'Return';
$string['groupfor'] = "for group";
$string['groupinfo'] = 'Info about selected group';

View File

@ -0,0 +1,3 @@
<p align="center"><b>Delete student attempts for this lesson (user id)</b></p>
<p>Type a username in here and click "Save Changes" to delete all attempts and grades for that user.</p>

View File

@ -37,6 +37,7 @@ define('RISK_XSS', 0x0004);
define('RISK_PERSONAL', 0x0008);
define('RISK_SPAM', 0x0010);
require_once($CFG->dirroot.'/group/lib.php');
$context_cache = array(); // Cache of all used context objects for performance (by level and instance)
$context_cache_id = array(); // Index to above cache by id
@ -442,8 +443,8 @@ function has_capability($capability, $context=NULL, $userid=NULL, $doanything=tr
case CONTEXT_GROUP:
// Find course.
$group = get_record('groups','id',$context->instanceid);
$courseinstance = get_context_instance(CONTEXT_COURSE, $group->courseid);
$courseid = groups_get_course($context->instanceid);
$courseinstance = get_context_instance(CONTEXT_COURSE, $courseid);
$parentcats = get_parent_cats($courseinstance, CONTEXT_COURSE);
foreach ($parentcats as $parentcat) {
@ -601,8 +602,8 @@ function capability_search($capability, $context, $capabilities, $switchroleacti
break;
case CONTEXT_GROUP: // 1 to 1 to course
$group = get_record('groups','id',$context->instanceid);
$parentcontext = get_context_instance(CONTEXT_COURSE, $group->courseid);
$courseid = groups_get_course($context->instanceid);
$parentcontext = get_context_instance(CONTEXT_COURSE, $courseid);
$permission = capability_search($capability, $parentcontext, $capabilities);
break;
@ -1150,10 +1151,10 @@ function capability_prohibits($capability, $context, $sum='', $array='') {
case CONTEXT_GROUP:
// 1 to 1 to course.
if (!$group = get_record('groups','id',$context->instanceid)) {
if (!$courseid = groups_get_course($context->instanceid)) {
return false;
}
$parent = get_context_instance(CONTEXT_COURSE, $group->courseid);
$parent = get_context_instance(CONTEXT_COURSE, $courseid);
return capability_prohibits($capability, $parent);
break;
@ -1528,7 +1529,8 @@ function validate_context($contextlevel, $instanceid) {
return (boolean)count_records('course', 'id', $instanceid);
case CONTEXT_GROUP:
return (boolean)count_records('groups', 'id', $instanceid);
//return (boolean)count_records('groups_groups', 'id', $instanceid); //TODO:DONOTCOMMIT:
return groups_group_exists($instanceid);
case CONTEXT_MODULE:
return (boolean)count_records('course_modules', 'id', $instanceid);
@ -1858,7 +1860,7 @@ function role_assign($roleid, $userid, $groupid, $contextid, $timestart=0, $time
return false;
}
if ($groupid && !record_exists('groups', 'id', $groupid)) {
if ($groupid && !groups_group_exists($groupid)) {
debugging('Group ID '.intval($groupid).' does not exist!');
return false;
}
@ -2337,8 +2339,8 @@ function print_context_name($context) {
break;
case CONTEXT_GROUP: // 1 to 1 to course
if ($group = get_record('groups', 'id', $context->instanceid)) {
$name = get_string('group').': '.$group->name;
if ($name = groups_get_group_name($context->instanceid)) {
$name = get_string('group').': '. $name;
}
break;
@ -2598,7 +2600,7 @@ function get_parent_contexts($context) {
break;
case CONTEXT_GROUP: // 1 to 1 to course
if (!$group = get_record('groups','id',$context->instanceid)) {
if (! $group = groups_get_group($context->instanceid)) {
return array();
}
if ($parent = get_context_instance(CONTEXT_COURSE, $group->courseid)) {
@ -3374,4 +3376,4 @@ function user_has_role_assignment($userid, $roleid, $contextid=0) {
return record_exists('role_assignments', 'userid', $userid, 'roleid', $roleid);
}
}
?>
?>

File diff suppressed because it is too large Load Diff

View File

@ -1,316 +0,0 @@
<?php
/*
V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Made table name configurable - by David Johnson djohnson@inpro.net
Encryption by Ari Kuorikoski <ari.kuorikoski@finebyte.com>
Set tabs to 4 for best viewing.
Latest version of ADODB is available at http://php.weblogs.com/adodb
======================================================================
This file provides PHP4 session management using the ADODB database
wrapper library.
Example
=======
GLOBAL $HTTP_SESSION_VARS;
include('adodb.inc.php');
#---------------------------------#
include('adodb-cryptsession.php');
#---------------------------------#
session_start();
session_register('AVAR');
$HTTP_SESSION_VARS['AVAR'] += 1;
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
Installation
============
1. Create a new database in MySQL or Access "sessions" like
so:
create table sessions (
SESSKEY char(32) not null,
EXPIRY int(11) unsigned not null,
EXPIREREF varchar(64),
DATA CLOB,
primary key (sesskey)
);
2. Then define the following parameters. You can either modify
this file, or define them before this file is included:
$ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';
$ADODB_SESSION_CONNECT='server to connect to';
$ADODB_SESSION_USER ='user';
$ADODB_SESSION_PWD ='password';
$ADODB_SESSION_DB ='database';
$ADODB_SESSION_TBL = 'sessions'
3. Recommended is PHP 4.0.2 or later. There are documented
session bugs in earlier versions of PHP.
*/
include_once('crypt.inc.php');
if (!defined('_ADODB_LAYER')) {
include (dirname(__FILE__).'/adodb.inc.php');
}
/* if database time and system time is difference is greater than this, then give warning */
define('ADODB_SESSION_SYNCH_SECS',60);
if (!defined('ADODB_SESSION')) {
define('ADODB_SESSION',1);
GLOBAL $ADODB_SESSION_CONNECT,
$ADODB_SESSION_DRIVER,
$ADODB_SESSION_USER,
$ADODB_SESSION_PWD,
$ADODB_SESSION_DB,
$ADODB_SESS_CONN,
$ADODB_SESS_LIFE,
$ADODB_SESS_DEBUG,
$ADODB_SESS_INSERT,
$ADODB_SESSION_EXPIRE_NOTIFY;
//$ADODB_SESS_DEBUG = true;
/* SET THE FOLLOWING PARAMETERS */
if (empty($ADODB_SESSION_DRIVER)) {
$ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='root';
$ADODB_SESSION_PWD ='';
$ADODB_SESSION_DB ='xphplens_2';
}
if (empty($ADODB_SESSION_TBL)){
$ADODB_SESSION_TBL = 'sessions';
}
if (empty($ADODB_SESSION_EXPIRE_NOTIFY)) {
$ADODB_SESSION_EXPIRE_NOTIFY = false;
}
function ADODB_Session_Key()
{
$ADODB_CRYPT_KEY = 'CRYPTED ADODB SESSIONS ROCK!';
/* USE THIS FUNCTION TO CREATE THE ENCRYPTION KEY FOR CRYPTED SESSIONS */
/* Crypt the used key, $ADODB_CRYPT_KEY as key and session_ID as SALT */
return crypt($ADODB_CRYPT_KEY, session_ID());
}
$ADODB_SESS_LIFE = ini_get('session.gc_maxlifetime');
if ($ADODB_SESS_LIFE <= 1) {
// bug in PHP 4.0.3 pl 1 -- how about other versions?
//print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $ADODB_SESS_LIFE</h3>";
$ADODB_SESS_LIFE=1440;
}
function adodb_sess_open($save_path, $session_name)
{
GLOBAL $ADODB_SESSION_CONNECT,
$ADODB_SESSION_DRIVER,
$ADODB_SESSION_USER,
$ADODB_SESSION_PWD,
$ADODB_SESSION_DB,
$ADODB_SESS_CONN,
$ADODB_SESS_DEBUG;
$ADODB_SESS_INSERT = false;
if (isset($ADODB_SESS_CONN)) return true;
$ADODB_SESS_CONN = ADONewConnection($ADODB_SESSION_DRIVER);
if (!empty($ADODB_SESS_DEBUG)) {
$ADODB_SESS_CONN->debug = true;
print" conn=$ADODB_SESSION_CONNECT user=$ADODB_SESSION_USER pwd=$ADODB_SESSION_PWD db=$ADODB_SESSION_DB ";
}
return $ADODB_SESS_CONN->PConnect($ADODB_SESSION_CONNECT,
$ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
}
function adodb_sess_close()
{
global $ADODB_SESS_CONN;
if ($ADODB_SESS_CONN) $ADODB_SESS_CONN->Close();
return true;
}
function adodb_sess_read($key)
{
$Crypt = new MD5Crypt;
global $ADODB_SESS_CONN,$ADODB_SESS_INSERT,$ADODB_SESSION_TBL;
$rs = $ADODB_SESS_CONN->Execute("SELECT data FROM $ADODB_SESSION_TBL WHERE sesskey = '$key' AND expiry >= " . time());
if ($rs) {
if ($rs->EOF) {
$ADODB_SESS_INSERT = true;
$v = '';
} else {
// Decrypt session data
$v = rawurldecode($Crypt->Decrypt(reset($rs->fields), ADODB_Session_Key()));
}
$rs->Close();
return $v;
}
else $ADODB_SESS_INSERT = true;
return '';
}
function adodb_sess_write($key, $val)
{
$Crypt = new MD5Crypt;
global $ADODB_SESS_INSERT,$ADODB_SESS_CONN, $ADODB_SESS_LIFE, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
$expiry = time() + $ADODB_SESS_LIFE;
// encrypt session data..
$val = $Crypt->Encrypt(rawurlencode($val), ADODB_Session_Key());
$arr = array('sesskey' => $key, 'expiry' => $expiry, 'data' => $val);
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
$var = reset($ADODB_SESSION_EXPIRE_NOTIFY);
global $$var;
$arr['expireref'] = $$var;
}
$rs = $ADODB_SESS_CONN->Replace($ADODB_SESSION_TBL,
$arr,
'sesskey',$autoQuote = true);
if (!$rs) {
ADOConnection::outp( '<p>Session Replace: '.$ADODB_SESS_CONN->ErrorMsg().'</p>',false);
} else {
// bug in access driver (could be odbc?) means that info is not commited
// properly unless select statement executed in Win2000
if ($ADODB_SESS_CONN->databaseType == 'access') $rs = $ADODB_SESS_CONN->Execute("select sesskey from $ADODB_SESSION_TBL WHERE sesskey='$key'");
}
return isset($rs);
}
function adodb_sess_destroy($key)
{
global $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
reset($ADODB_SESSION_EXPIRE_NOTIFY);
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$ADODB_SESS_CONN->SetFetchMode($savem);
if ($rs) {
$ADODB_SESS_CONN->BeginTrans();
while (!$rs->EOF) {
$ref = $rs->fields[0];
$key = $rs->fields[1];
$fn($ref,$key);
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$rs->MoveNext();
}
$ADODB_SESS_CONN->CommitTrans();
}
} else {
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE sesskey = '$key'";
$rs = $ADODB_SESS_CONN->Execute($qry);
}
return $rs ? true : false;
}
function adodb_sess_gc($maxlifetime) {
global $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY,$ADODB_SESS_DEBUG;
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
reset($ADODB_SESSION_EXPIRE_NOTIFY);
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < " . time());
$ADODB_SESS_CONN->SetFetchMode($savem);
if ($rs) {
$ADODB_SESS_CONN->BeginTrans();
while (!$rs->EOF) {
$ref = $rs->fields[0];
$key = $rs->fields[1];
$fn($ref,$key);
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$rs->MoveNext();
}
$ADODB_SESS_CONN->CommitTrans();
}
} else {
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE expiry < " . time();
$ADODB_SESS_CONN->Execute($qry);
}
// suggested by Cameron, "GaM3R" <gamr@outworld.cx>
if (defined('ADODB_SESSION_OPTIMIZE'))
{
switch( $ADODB_SESSION_DRIVER ) {
case 'mysql':
case 'mysqlt':
$opt_qry = 'OPTIMIZE TABLE '.$ADODB_SESSION_TBL;
break;
case 'postgresql':
case 'postgresql7':
$opt_qry = 'VACUUM '.$ADODB_SESSION_TBL;
break;
}
}
if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
$rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
if ($rs && !$rs->EOF) {
$dbts = reset($rs->fields);
$rs->Close();
$dbt = $ADODB_SESS_CONN->UnixTimeStamp($dbts);
$t = time();
if (abs($dbt - $t) >= ADODB_SESSION_SYNCH_SECS) {
global $HTTP_SERVER_VARS;
$msg =
__FILE__.": Server time for webserver {$HTTP_SERVER_VARS['HTTP_HOST']} not in synch with database: database=$dbt ($dbts), webserver=$t (diff=".(abs($dbt-$t)/3600)." hrs)";
error_log($msg);
if ($ADODB_SESS_DEBUG) ADOConnection::outp("<p>$msg</p>");
}
}
return true;
}
session_module_name('user');
session_set_save_handler(
"adodb_sess_open",
"adodb_sess_close",
"adodb_sess_read",
"adodb_sess_write",
"adodb_sess_destroy",
"adodb_sess_gc");
}
/* TEST SCRIPT -- UNCOMMENT */
/*
if (0) {
GLOBAL $HTTP_SESSION_VARS;
session_start();
session_register('AVAR');
$HTTP_SESSION_VARS['AVAR'] += 1;
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
}
*/
?>

View File

@ -1,919 +0,0 @@
<?php
/**
* @version V3.40 7 April 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://php.weblogs.com
*
*/
/**
* RecordSet class that represents the dataset returned by the database.
* To keep memory overhead low, this class holds only the current row in memory.
* No prefetching of data is done, so the RecordCount() can return -1 ( which
* means recordcount not known).
*/
class ADORecordSet {
/*
* public variables
*/
var $dataProvider = "native";
var $fields = false; /* / holds the current row data */
var $blobSize = 64; /* / any varchar/char field this size or greater is treated as a blob */
/* / in other words, we use a text area for editting. */
var $canSeek = false; /* / indicates that seek is supported */
var $sql; /* / sql text */
var $EOF = false; /* / Indicates that the current record position is after the last record in a Recordset object. */
var $emptyTimeStamp = '&nbsp;'; /* / what to display when $time==0 */
var $emptyDate = '&nbsp;'; /* / what to display when $time==0 */
var $debug = false;
var $timeCreated=0; /* / datetime in Unix format rs created -- for cached recordsets */
var $bind = false; /* / used by Fields() to hold array - should be private? */
var $fetchMode; /* / default fetch mode */
var $connection = false; /* / the parent connection */
/*
* private variables
*/
var $_numOfRows = -1; /** number of rows, or -1 */
var $_numOfFields = -1; /** number of fields in recordset */
var $_queryID = -1; /** This variable keeps the result link identifier. */
var $_currentRow = -1; /** This variable keeps the current row in the Recordset. */
var $_closed = false; /** has recordset been closed */
var $_inited = false; /** Init() should only be called once */
var $_obj; /** Used by FetchObj */
var $_names; /** Used by FetchObj */
var $_currentPage = -1; /** Added by Iván Oliva to implement recordset pagination */
var $_atFirstPage = false; /** Added by Iván Oliva to implement recordset pagination */
var $_atLastPage = false; /** Added by Iván Oliva to implement recordset pagination */
var $_lastPageNo = -1;
var $_maxRecordCount = 0;
var $dateHasTime = false;
/**
* Constructor
*
* @param queryID this is the queryID returned by ADOConnection->_query()
*
*/
function ADORecordSet($queryID)
{
$this->_queryID = $queryID;
}
function Init()
{
if ($this->_inited) return;
$this->_inited = true;
if ($this->_queryID) @$this->_initrs();
else {
$this->_numOfRows = 0;
$this->_numOfFields = 0;
}
if ($this->_numOfRows != 0 && $this->_numOfFields && $this->_currentRow == -1) {
$this->_currentRow = 0;
if ($this->EOF = ($this->_fetch() === false)) {
$this->_numOfRows = 0; /* _numOfRows could be -1 */
}
} else {
$this->EOF = true;
}
}
/**
* Generate a SELECT tag string from a recordset, and return the string.
* If the recordset has 2 cols, we treat the 1st col as the containing
* the text to display to the user, and 2nd col as the return value. Default
* strings are compared with the FIRST column.
*
* @param name name of SELECT tag
* @param [defstr] the value to hilite. Use an array for multiple hilites for listbox.
* @param [blank1stItem] true to leave the 1st item in list empty
* @param [multiple] true for listbox, false for popup
* @param [size] #rows to show for listbox. not used by popup
* @param [selectAttr] additional attributes to defined for SELECT tag.
* useful for holding javascript onChange='...' handlers.
& @param [compareFields0] when we have 2 cols in recordset, we compare the defstr with
* column 0 (1st col) if this is true. This is not documented.
*
* @return HTML
*
* changes by glen.davies@cce.ac.nz to support multiple hilited items
*/
function GetMenu($name,$defstr='',$blank1stItem=true,$multiple=false,
$size=0, $selectAttr='',$compareFields0=true)
{
include_once(ADODB_DIR.'/adodb-lib.inc.php');
return _adodb_getmenu($this, $name,$defstr,$blank1stItem,$multiple,
$size, $selectAttr,$compareFields0);
}
/**
* Generate a SELECT tag string from a recordset, and return the string.
* If the recordset has 2 cols, we treat the 1st col as the containing
* the text to display to the user, and 2nd col as the return value. Default
* strings are compared with the SECOND column.
*
*/
function GetMenu2($name,$defstr='',$blank1stItem=true,$multiple=false,$size=0, $selectAttr='')
{
include_once(ADODB_DIR.'/adodb-lib.inc.php');
return _adodb_getmenu($this,$name,$defstr,$blank1stItem,$multiple,
$size, $selectAttr,false);
}
/**
* return recordset as a 2-dimensional array.
*
* @param [nRows] is the number of rows to return. -1 means every row.
*
* @return an array indexed by the rows (0-based) from the recordset
*/
function GetArray($nRows = -1)
{
global $ADODB_EXTENSION; if ($ADODB_EXTENSION) return adodb_getall($this,$nRows);
$results = array();
$cnt = 0;
while (!$this->EOF && $nRows != $cnt) {
$results[] = $this->fields;
$this->MoveNext();
$cnt++;
}
return $results;
}
/*
* Some databases allow multiple recordsets to be returned. This function
* will return true if there is a next recordset, or false if no more.
*/
function NextRecordSet()
{
return false;
}
/**
* return recordset as a 2-dimensional array.
* Helper function for ADOConnection->SelectLimit()
*
* @param offset is the row to start calculations from (1-based)
* @param [nrows] is the number of rows to return
*
* @return an array indexed by the rows (0-based) from the recordset
*/
function GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
return $this->GetArray($nrows);
}
$this->Move($offset);
$results = array();
$cnt = 0;
while (!$this->EOF && $nrows != $cnt) {
$results[$cnt++] = $this->fields;
$this->MoveNext();
}
return $results;
}
/**
* Synonym for GetArray() for compatibility with ADO.
*
* @param [nRows] is the number of rows to return. -1 means every row.
*
* @return an array indexed by the rows (0-based) from the recordset
*/
function GetRows($nRows = -1)
{
return $this->GetArray($nRows);
}
/**
* return whole recordset as a 2-dimensional associative array if there are more than 2 columns.
* The first column is treated as the key and is not included in the array.
* If there is only 2 columns, it will return a 1 dimensional array of key-value pairs unless
* $force_array == true.
*
* @param [force_array] has only meaning if we have 2 data columns. If false, a 1 dimensional
* array is returned, otherwise a 2 dimensional array is returned. If this sounds confusing,
* read the source.
*
* @param [first2cols] means if there are more than 2 cols, ignore the remaining cols and
* instead of returning array[col0] => array(remaining cols), return array[col0] => col1
*
* @return an associative array indexed by the first column of the array,
* or false if the data has less than 2 cols.
*/
function GetAssoc($force_array = false, $first2cols = false) {
$cols = $this->_numOfFields;
if ($cols < 2) {
return false;
}
$numIndex = isset($this->fields[0]);
$results = array();
if (!$first2cols && ($cols > 2 || $force_array)) {
if ($numIndex) {
while (!$this->EOF) {
$results[trim($this->fields[0])] = array_slice($this->fields, 1);
$this->MoveNext();
}
} else {
while (!$this->EOF) {
$results[trim(reset($this->fields))] = array_slice($this->fields, 1);
$this->MoveNext();
}
}
} else {
/* return scalar values */
if ($numIndex) {
while (!$this->EOF) {
/* some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string */
$results[trim(($this->fields[0]))] = $this->fields[1];
$this->MoveNext();
}
} else {
while (!$this->EOF) {
/* some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string */
$v1 = trim(reset($this->fields));
$v2 = ''.next($this->fields);
$results[$v1] = $v2;
$this->MoveNext();
}
}
}
return $results;
}
/**
*
* @param v is the character timestamp in YYYY-MM-DD hh:mm:ss format
* @param fmt is the format to apply to it, using date()
*
* @return a timestamp formated as user desires
*/
function UserTimeStamp($v,$fmt='Y-m-d H:i:s')
{
$tt = $this->UnixTimeStamp($v);
/* $tt == -1 if pre TIMESTAMP_FIRST_YEAR */
if (($tt === false || $tt == -1) && $v != false) return $v;
if ($tt == 0) return $this->emptyTimeStamp;
return adodb_date($fmt,$tt);
}
/**
* @param v is the character date in YYYY-MM-DD format, returned by database
* @param fmt is the format to apply to it, using date()
*
* @return a date formated as user desires
*/
function UserDate($v,$fmt='Y-m-d')
{
$tt = $this->UnixDate($v);
/* $tt == -1 if pre TIMESTAMP_FIRST_YEAR */
if (($tt === false || $tt == -1) && $v != false) return $v;
else if ($tt == 0) return $this->emptyDate;
else if ($tt == -1) { /* pre-TIMESTAMP_FIRST_YEAR */
}
return adodb_date($fmt,$tt);
}
/**
* @param $v is a date string in YYYY-MM-DD format
*
* @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
*/
function UnixDate($v)
{
if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|",
($v), $rr)) return false;
if ($rr[1] <= 1903) return 0;
/* h-m-s-MM-DD-YY */
return @adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]);
}
/**
* @param $v is a timestamp string in YYYY-MM-DD HH-NN-SS format
*
* @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
*/
function UnixTimeStamp($v)
{
if (!preg_match(
"|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
($v), $rr)) return false;
if ($rr[1] <= 1903 && $rr[2]<= 1) return 0;
/* h-m-s-MM-DD-YY */
if (!isset($rr[5])) return adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]);
return @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]);
}
/**
* PEAR DB Compat - do not use internally
*/
function Free()
{
return $this->Close();
}
/**
* PEAR DB compat, number of rows
*/
function NumRows()
{
return $this->_numOfRows;
}
/**
* PEAR DB compat, number of cols
*/
function NumCols()
{
return $this->_numOfFields;
}
/**
* Fetch a row, returning false if no more rows.
* This is PEAR DB compat mode.
*
* @return false or array containing the current record
*/
function FetchRow()
{
if ($this->EOF) return false;
$arr = $this->fields;
$this->_currentRow++;
if (!$this->_fetch()) $this->EOF = true;
return $arr;
}
/**
* Fetch a row, returning PEAR_Error if no more rows.
* This is PEAR DB compat mode.
*
* @return DB_OK or error object
*/
function FetchInto(&$arr)
{
if ($this->EOF) return (defined('PEAR_ERROR_RETURN')) ? new PEAR_Error('EOF',-1): false;
$arr = $this->fields;
$this->MoveNext();
return 1; /* DB_OK */
}
/**
* Move to the first row in the recordset. Many databases do NOT support this.
*
* @return true or false
*/
function MoveFirst()
{
if ($this->_currentRow == 0) return true;
return $this->Move(0);
}
/**
* Move to the last row in the recordset.
*
* @return true or false
*/
function MoveLast()
{
if ($this->_numOfRows >= 0) return $this->Move($this->_numOfRows-1);
if ($this->EOF) return false;
while (!$this->EOF) {
$f = $this->fields;
$this->MoveNext();
}
$this->fields = $f;
$this->EOF = false;
return true;
}
/**
* Move to next record in the recordset.
*
* @return true if there still rows available, or false if there are no more rows (EOF).
*/
function MoveNext()
{
if (!$this->EOF) {
$this->_currentRow++;
if ($this->_fetch()) return true;
}
$this->EOF = true;
/* -- tested error handling when scrolling cursor -- seems useless.
$conn = $this->connection;
if ($conn && $conn->raiseErrorFn && ($errno = $conn->ErrorNo())) {
$fn = $conn->raiseErrorFn;
$fn($conn->databaseType,'MOVENEXT',$errno,$conn->ErrorMsg().' ('.$this->sql.')',$conn->host,$conn->database);
}
*/
return false;
}
/**
* Random access to a specific row in the recordset. Some databases do not support
* access to previous rows in the databases (no scrolling backwards).
*
* @param rowNumber is the row to move to (0-based)
*
* @return true if there still rows available, or false if there are no more rows (EOF).
*/
function Move($rowNumber = 0)
{
$this->EOF = false;
if ($rowNumber == $this->_currentRow) return true;
if ($rowNumber >= $this->_numOfRows)
if ($this->_numOfRows != -1) $rowNumber = $this->_numOfRows-2;
if ($this->canSeek) {
if ($this->_seek($rowNumber)) {
$this->_currentRow = $rowNumber;
if ($this->_fetch()) {
return true;
}
} else {
$this->EOF = true;
return false;
}
} else {
if ($rowNumber < $this->_currentRow) return false;
global $ADODB_EXTENSION;
if ($ADODB_EXTENSION) {
while (!$this->EOF && $this->_currentRow < $rowNumber) {
adodb_movenext($this);
}
} else {
while (! $this->EOF && $this->_currentRow < $rowNumber) {
$this->_currentRow++;
if (!$this->_fetch()) $this->EOF = true;
}
}
return !($this->EOF);
}
$this->fields = false;
$this->EOF = true;
return false;
}
/**
* Get the value of a field in the current row by column name.
* Will not work if ADODB_FETCH_MODE is set to ADODB_FETCH_NUM.
*
* @param colname is the field to access
*
* @return the value of $colname column
*/
function Fields($colname)
{
return $this->fields[$colname];
}
function GetAssocKeys($upper=true)
{
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
if ($upper === 2) $this->bind[$o->name] = $i;
else $this->bind[($upper) ? strtoupper($o->name) : strtolower($o->name)] = $i;
}
}
/**
* Use associative array to get fields array for databases that do not support
* associative arrays. Submitted by Paolo S. Asioli paolo.asioli@libero.it
*
* If you don't want uppercase cols, set $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC
* before you execute your SQL statement, and access $rs->fields['col'] directly.
*
* $upper 0 = lowercase, 1 = uppercase, 2 = whatever is returned by FetchField
*/
function GetRowAssoc($upper=1)
{
if (!$this->bind) {
$this->GetAssocKeys($upper);
}
$record = array();
foreach($this->bind as $k => $v) {
$record[$k] = $this->fields[$v];
}
return $record;
}
/**
* Clean up recordset
*
* @return true or false
*/
function Close()
{
/* free connection object - this seems to globally free the object */
/* and not merely the reference, so don't do this... */
/* $this->connection = false; */
if (!$this->_closed) {
$this->_closed = true;
return $this->_close();
} else
return true;
}
/**
* synonyms RecordCount and RowCount
*
* @return the number of rows or -1 if this is not supported
*/
function RecordCount() {return $this->_numOfRows;}
/*
* If we are using PageExecute(), this will return the maximum possible rows
* that can be returned when paging a recordset.
*/
function MaxRecordCount()
{
return ($this->_maxRecordCount) ? $this->_maxRecordCount : $this->RecordCount();
}
/**
* synonyms RecordCount and RowCount
*
* @return the number of rows or -1 if this is not supported
*/
function RowCount() {return $this->_numOfRows;}
/**
* Portable RecordCount. Pablo Roca <pabloroca@mvps.org>
*
* @return the number of records from a previous SELECT. All databases support this.
*
* But aware possible problems in multiuser environments. For better speed the table
* must be indexed by the condition. Heavy test this before deploying.
*/
function PO_RecordCount($table="", $condition="") {
$lnumrows = $this->_numOfRows;
/* the database doesn't support native recordcount, so we do a workaround */
if ($lnumrows == -1 && $this->connection) {
IF ($table) {
if ($condition) $condition = " WHERE " . $condition;
$resultrows = &$this->connection->Execute("SELECT COUNT(*) FROM $table $condition");
if ($resultrows) $lnumrows = reset($resultrows->fields);
}
}
return $lnumrows;
}
/**
* @return the current row in the recordset. If at EOF, will return the last row. 0-based.
*/
function CurrentRow() {return $this->_currentRow;}
/**
* synonym for CurrentRow -- for ADO compat
*
* @return the current row in the recordset. If at EOF, will return the last row. 0-based.
*/
function AbsolutePosition() {return $this->_currentRow;}
/**
* @return the number of columns in the recordset. Some databases will set this to 0
* if no records are returned, others will return the number of columns in the query.
*/
function FieldCount() {return $this->_numOfFields;}
/**
* Get the ADOFieldObject of a specific column.
*
* @param fieldoffset is the column position to access(0-based).
*
* @return the ADOFieldObject for that column, or false.
*/
function &FetchField($fieldoffset)
{
/* must be defined by child class */
}
/**
* Get the ADOFieldObjects of all columns in an array.
*
*/
function FieldTypesArray()
{
$arr = array();
for ($i=0, $max=$this->_numOfFields; $i < $max; $i++)
$arr[] = $this->FetchField($i);
return $arr;
}
/**
* Return the fields array of the current row as an object for convenience.
* The default case is lowercase field names.
*
* @return the object with the properties set to the fields of the current row
*/
function &FetchObj()
{
return FetchObject(false);
}
/**
* Return the fields array of the current row as an object for convenience.
* The default case is uppercase.
*
* @param $isupper to set the object property names to uppercase
*
* @return the object with the properties set to the fields of the current row
*/
function &FetchObject($isupper=true)
{
if (empty($this->_obj)) {
$this->_obj = new ADOFetchObj();
$this->_names = array();
for ($i=0; $i <$this->_numOfFields; $i++) {
$f = $this->FetchField($i);
$this->_names[] = $f->name;
}
}
$i = 0;
$o = &$this->_obj;
for ($i=0; $i <$this->_numOfFields; $i++) {
$name = $this->_names[$i];
if ($isupper) $n = strtoupper($name);
else $n = $name;
$o->$n = $this->Fields($name);
}
return $o;
}
/**
* Return the fields array of the current row as an object for convenience.
* The default is lower-case field names.
*
* @return the object with the properties set to the fields of the current row,
* or false if EOF
*
* Fixed bug reported by tim@orotech.net
*/
function &FetchNextObj()
{
return $this->FetchNextObject(false);
}
/**
* Return the fields array of the current row as an object for convenience.
* The default is upper case field names.
*
* @param $isupper to set the object property names to uppercase
*
* @return the object with the properties set to the fields of the current row,
* or false if EOF
*
* Fixed bug reported by tim@orotech.net
*/
function &FetchNextObject($isupper=true)
{
$o = false;
if ($this->_numOfRows != 0 && !$this->EOF) {
$o = $this->FetchObject($isupper);
$this->_currentRow++;
if ($this->_fetch()) return $o;
}
$this->EOF = true;
return $o;
}
/**
* Get the metatype of the column. This is used for formatting. This is because
* many databases use different names for the same type, so we transform the original
* type to our standardised version which uses 1 character codes:
*
* @param t is the type passed in. Normally is ADOFieldObject->type.
* @param len is the maximum length of that field. This is because we treat character
* fields bigger than a certain size as a 'B' (blob).
* @param fieldobj is the field object returned by the database driver. Can hold
* additional info (eg. primary_key for mysql).
*
* @return the general type of the data:
* C for character < 200 chars
* X for teXt (>= 200 chars)
* B for Binary
* N for numeric floating point
* D for date
* T for timestamp
* L for logical/Boolean
* I for integer
* R for autoincrement counter/integer
*
*
*/
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
/* changed in 2.32 to hashing instead of switch stmt for speed... */
static $typeMap = array(
'VARCHAR' => 'C',
'VARCHAR2' => 'C',
'CHAR' => 'C',
'C' => 'C',
'STRING' => 'C',
'NCHAR' => 'C',
'NVARCHAR' => 'C',
'VARYING' => 'C',
'BPCHAR' => 'C',
'CHARACTER' => 'C',
'INTERVAL' => 'C', # Postgres
##
'LONGCHAR' => 'X',
'TEXT' => 'X',
'M' => 'X',
'X' => 'X',
'CLOB' => 'X',
'NCLOB' => 'X',
'LVARCHAR' => 'X',
##
'BLOB' => 'B',
'NTEXT' => 'B',
'BINARY' => 'B',
'VARBINARY' => 'B',
'LONGBINARY' => 'B',
'B' => 'B',
##
'YEAR' => 'D', /* mysql */
'DATE' => 'D',
'D' => 'D',
##
'TIME' => 'T',
'TIMESTAMP' => 'T',
'DATETIME' => 'T',
'TIMESTAMPTZ' => 'T',
'T' => 'T',
##
'BOOLEAN' => 'L',
'BIT' => 'L',
'L' => 'L',
##
'COUNTER' => 'R',
'R' => 'R',
'SERIAL' => 'R', /* ifx */
##
'INT' => 'I',
'INTEGER' => 'I',
'SHORT' => 'I',
'TINYINT' => 'I',
'SMALLINT' => 'I',
'I' => 'I',
##
'LONG' => 'N', /* interbase is numeric, oci8 is blob */
'BIGINT' => 'N', /* this is bigger than PHP 32-bit integers */
'DECIMAL' => 'N',
'DEC' => 'N',
'REAL' => 'N',
'DOUBLE' => 'N',
'DOUBLE PRECISION' => 'N',
'SMALLFLOAT' => 'N',
'FLOAT' => 'N',
'NUMBER' => 'N',
'NUM' => 'N',
'NUMERIC' => 'N',
'MONEY' => 'N',
## informix 9.2
'SQLINT' => 'I',
'SQLSERIAL' => 'I',
'SQLSMINT' => 'I',
'SQLSMFLOAT' => 'N',
'SQLFLOAT' => 'N',
'SQLMONEY' => 'N',
'SQLDECIMAL' => 'N',
'SQLDATE' => 'D',
'SQLVCHAR' => 'C',
'SQLCHAR' => 'C',
'SQLDTIME' => 'T',
'SQLINTERVAL' => 'N',
'SQLBYTES' => 'B',
'SQLTEXT' => 'X'
);
$tmap = false;
$t = strtoupper($t);
$tmap = @$typeMap[$t];
switch ($tmap) {
case 'C':
/* is the char field is too long, return as text field... */
if (!empty($this)) {
if ($len > $this->blobSize) return 'X';
} else if ($len > 250) {
return 'X';
}
return 'C';
case 'I':
if (!empty($fieldobj->primary_key)) return 'R';
return 'I';
case false:
return 'N';
case 'B':
if (isset($fieldobj->binary))
return ($fieldobj->binary) ? 'B' : 'X';
return 'B';
case 'D':
if ($this->dateHasTime) return 'T';
return 'D';
default:
if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
return $tmap;
}
}
function _close() {}
/**
* set/returns the current recordset page when paginating
*/
function AbsolutePage($page=-1)
{
if ($page != -1) $this->_currentPage = $page;
return $this->_currentPage;
}
/**
* set/returns the status of the atFirstPage flag when paginating
*/
function AtFirstPage($status=false)
{
if ($status != false) $this->_atFirstPage = $status;
return $this->_atFirstPage;
}
function LastPageNo($page = false)
{
if ($page != false) $this->_lastPageNo = $page;
return $this->_lastPageNo;
}
/**
* set/returns the status of the atLastPage flag when paginating
*/
function AtLastPage($status=false)
{
if ($status != false) $this->_atLastPage = $status;
return $this->_atLastPage;
}
} /* end class ADORecordSet */
?>

View File

@ -1,439 +0,0 @@
<?php
/*
V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version of ADODB is available at http://php.weblogs.com/adodb
======================================================================
This file provides PHP4 session management using the ADODB database
wrapper library, using Oracle CLOB's to store data. Contributed by achim.gosse@ddd.de.
Example
=======
GLOBAL $HTTP_SESSION_VARS;
include('adodb.inc.php');
include('adodb-session.php');
session_start();
session_register('AVAR');
$HTTP_SESSION_VARS['AVAR'] += 1;
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
To force non-persistent connections, call adodb_session_open first before session_start():
GLOBAL $HTTP_SESSION_VARS;
include('adodb.inc.php');
include('adodb-session.php');
adodb_session_open(false,false,false);
session_start();
session_register('AVAR');
$HTTP_SESSION_VARS['AVAR'] += 1;
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
Installation
============
1. Create this table in your database (syntax might vary depending on your db):
create table sessions (
SESSKEY char(32) not null,
EXPIRY int(11) unsigned not null,
EXPIREREF varchar(64),
DATA CLOB,
primary key (sesskey)
);
2. Then define the following parameters in this file:
$ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';
$ADODB_SESSION_CONNECT='server to connect to';
$ADODB_SESSION_USER ='user';
$ADODB_SESSION_PWD ='password';
$ADODB_SESSION_DB ='database';
$ADODB_SESSION_TBL = 'sessions'
$ADODB_SESSION_USE_LOBS = false; (or, if you wanna use CLOBS (= 'CLOB') or ( = 'BLOB')
3. Recommended is PHP 4.0.6 or later. There are documented
session bugs in earlier versions of PHP.
4. If you want to receive notifications when a session expires, then
you can tag a session with an EXPIREREF, and before the session
record is deleted, we can call a function that will pass the EXPIREREF
as the first parameter, and the session key as the second parameter.
To do this, define a notification function, say NotifyFn:
function NotifyFn($expireref, $sesskey)
{
}
Then you need to define a global variable $ADODB_SESSION_EXPIRE_NOTIFY.
This is an array with 2 elements, the first being the name of the variable
you would like to store in the EXPIREREF field, and the 2nd is the
notification function's name.
In this example, we want to be notified when a user's session
has expired, so we store the user id in the global variable $USERID,
store this value in the EXPIREREF field:
$ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');
Then when the NotifyFn is called, we are passed the $USERID as the first
parameter, eg. NotifyFn($userid, $sesskey).
*/
if (!defined('_ADODB_LAYER')) {
include (dirname(__FILE__).'/adodb.inc.php');
}
if (!defined('ADODB_SESSION')) {
define('ADODB_SESSION',1);
/* if database time and system time is difference is greater than this, then give warning */
define('ADODB_SESSION_SYNCH_SECS',60);
/****************************************************************************************\
Global definitions
\****************************************************************************************/
GLOBAL $ADODB_SESSION_CONNECT,
$ADODB_SESSION_DRIVER,
$ADODB_SESSION_USER,
$ADODB_SESSION_PWD,
$ADODB_SESSION_DB,
$ADODB_SESS_CONN,
$ADODB_SESS_LIFE,
$ADODB_SESS_DEBUG,
$ADODB_SESSION_EXPIRE_NOTIFY,
$ADODB_SESSION_CRC,
$ADODB_SESSION_USE_LOBS;
if (!isset($ADODB_SESSION_USE_LOBS)) $ADODB_SESSION_USE_LOBS = 'CLOB';
$ADODB_SESS_LIFE = ini_get('session.gc_maxlifetime');
if ($ADODB_SESS_LIFE <= 1) {
// bug in PHP 4.0.3 pl 1 -- how about other versions?
//print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $ADODB_SESS_LIFE</h3>";
$ADODB_SESS_LIFE=1440;
}
$ADODB_SESSION_CRC = false;
//$ADODB_SESS_DEBUG = true;
//////////////////////////////////
/* SET THE FOLLOWING PARAMETERS */
//////////////////////////////////
if (empty($ADODB_SESSION_DRIVER)) {
$ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='root';
$ADODB_SESSION_PWD ='';
$ADODB_SESSION_DB ='xphplens_2';
}
if (empty($ADODB_SESSION_EXPIRE_NOTIFY)) {
$ADODB_SESSION_EXPIRE_NOTIFY = false;
}
// Made table name configurable - by David Johnson djohnson@inpro.net
if (empty($ADODB_SESSION_TBL)){
$ADODB_SESSION_TBL = 'sessions';
}
// defaulting $ADODB_SESSION_USE_LOBS
if (!isset($ADODB_SESSION_USE_LOBS) || empty($ADODB_SESSION_USE_LOBS)) {
$ADODB_SESSION_USE_LOBS = false;
}
/*
$ADODB_SESS['driver'] = $ADODB_SESSION_DRIVER;
$ADODB_SESS['connect'] = $ADODB_SESSION_CONNECT;
$ADODB_SESS['user'] = $ADODB_SESSION_USER;
$ADODB_SESS['pwd'] = $ADODB_SESSION_PWD;
$ADODB_SESS['db'] = $ADODB_SESSION_DB;
$ADODB_SESS['life'] = $ADODB_SESS_LIFE;
$ADODB_SESS['debug'] = $ADODB_SESS_DEBUG;
$ADODB_SESS['debug'] = $ADODB_SESS_DEBUG;
$ADODB_SESS['table'] = $ADODB_SESS_TBL;
*/
/****************************************************************************************\
Create the connection to the database.
If $ADODB_SESS_CONN already exists, reuse that connection
\****************************************************************************************/
function adodb_sess_open($save_path, $session_name,$persist=true)
{
GLOBAL $ADODB_SESS_CONN;
if (isset($ADODB_SESS_CONN)) return true;
GLOBAL $ADODB_SESSION_CONNECT,
$ADODB_SESSION_DRIVER,
$ADODB_SESSION_USER,
$ADODB_SESSION_PWD,
$ADODB_SESSION_DB,
$ADODB_SESS_DEBUG;
// cannot use & below - do not know why...
$ADODB_SESS_CONN = ADONewConnection($ADODB_SESSION_DRIVER);
if (!empty($ADODB_SESS_DEBUG)) {
$ADODB_SESS_CONN->debug = true;
ADOConnection::outp( " conn=$ADODB_SESSION_CONNECT user=$ADODB_SESSION_USER pwd=$ADODB_SESSION_PWD db=$ADODB_SESSION_DB ");
}
if ($persist) $ok = $ADODB_SESS_CONN->PConnect($ADODB_SESSION_CONNECT,
$ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
else $ok = $ADODB_SESS_CONN->Connect($ADODB_SESSION_CONNECT,
$ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
if (!$ok) ADOConnection::outp( "<p>Session: connection failed</p>",false);
}
/****************************************************************************************\
Close the connection
\****************************************************************************************/
function adodb_sess_close()
{
global $ADODB_SESS_CONN;
if ($ADODB_SESS_CONN) $ADODB_SESS_CONN->Close();
return true;
}
/****************************************************************************************\
Slurp in the session variables and return the serialized string
\****************************************************************************************/
function adodb_sess_read($key)
{
global $ADODB_SESS_CONN,$ADODB_SESSION_TBL,$ADODB_SESSION_CRC;
$rs = $ADODB_SESS_CONN->Execute("SELECT data FROM $ADODB_SESSION_TBL WHERE sesskey = '$key' AND expiry >= " . time());
if ($rs) {
if ($rs->EOF) {
$v = '';
} else
$v = rawurldecode(reset($rs->fields));
$rs->Close();
// new optimization adodb 2.1
$ADODB_SESSION_CRC = strlen($v).crc32($v);
return $v;
}
return ''; // thx to Jorma Tuomainen, webmaster#wizactive.com
}
/****************************************************************************************\
Write the serialized data to a database.
If the data has not been modified since adodb_sess_read(), we do not write.
\****************************************************************************************/
function adodb_sess_write($key, $val)
{
global
$ADODB_SESS_CONN,
$ADODB_SESS_LIFE,
$ADODB_SESSION_TBL,
$ADODB_SESS_DEBUG,
$ADODB_SESSION_CRC,
$ADODB_SESSION_EXPIRE_NOTIFY,
$ADODB_SESSION_DRIVER, // added
$ADODB_SESSION_USE_LOBS; // added
$expiry = time() + $ADODB_SESS_LIFE;
// crc32 optimization since adodb 2.1
// now we only update expiry date, thx to sebastian thom in adodb 2.32
if ($ADODB_SESSION_CRC !== false && $ADODB_SESSION_CRC == strlen($val).crc32($val)) {
if ($ADODB_SESS_DEBUG) echo "<p>Session: Only updating date - crc32 not changed</p>";
$qry = "UPDATE $ADODB_SESSION_TBL SET expiry=$expiry WHERE sesskey='$key' AND expiry >= " . time();
$rs = $ADODB_SESS_CONN->Execute($qry);
return true;
}
$val = rawurlencode($val);
$arr = array('sesskey' => $key, 'expiry' => $expiry, 'data' => $val);
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
$var = reset($ADODB_SESSION_EXPIRE_NOTIFY);
global $$var;
$arr['expireref'] = $$var;
}
if ($ADODB_SESSION_USE_LOBS === false) { // no lobs, simply use replace()
$rs = $ADODB_SESS_CONN->Replace($ADODB_SESSION_TBL,$arr, 'sesskey',$autoQuote = true);
if (!$rs) {
$err = $ADODB_SESS_CONN->ErrorMsg();
}
} else {
// what value shall we insert/update for lob row?
switch ($ADODB_SESSION_DRIVER) {
// empty_clob or empty_lob for oracle dbs
case "oracle":
case "oci8":
case "oci8po":
case "oci805":
$lob_value = sprintf("empty_%s()", strtolower($ADODB_SESSION_USE_LOBS));
break;
// null for all other
default:
$lob_value = "null";
break;
}
// do we insert or update? => as for sesskey
$res = $ADODB_SESS_CONN->Execute("select count(*) as cnt from $ADODB_SESSION_TBL where sesskey = '$key'");
if ($res && reset($res->fields) > 0) {
$qry = sprintf("update %s set expiry = %d, data = %s where sesskey = '%s'", $ADODB_SESSION_TBL, $expiry, $lob_value, $key);
} else {
// insert
$qry = sprintf("insert into %s (sesskey, expiry, data) values ('%s', %d, %s)", $ADODB_SESSION_TBL, $key, $expiry, $lob_value);
}
$err = "";
$rs1 = $ADODB_SESS_CONN->Execute($qry);
if (!$rs1) {
$err .= $ADODB_SESS_CONN->ErrorMsg()."\n";
}
$rs2 = $ADODB_SESS_CONN->UpdateBlob($ADODB_SESSION_TBL, 'data', $val, "sesskey='$key'", strtoupper($ADODB_SESSION_USE_LOBS));
if (!$rs2) {
$err .= $ADODB_SESS_CONN->ErrorMsg()."\n";
}
$rs = ($rs1 && $rs2) ? true : false;
}
if (!$rs) {
ADOConnection::outp( '<p>Session Replace: '.nl2br($err).'</p>',false);
} else {
// bug in access driver (could be odbc?) means that info is not commited
// properly unless select statement executed in Win2000
if ($ADODB_SESS_CONN->databaseType == 'access')
$rs = $ADODB_SESS_CONN->Execute("select sesskey from $ADODB_SESSION_TBL WHERE sesskey='$key'");
}
return !empty($rs);
}
function adodb_sess_destroy($key)
{
global $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
reset($ADODB_SESSION_EXPIRE_NOTIFY);
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$ADODB_SESS_CONN->SetFetchMode($savem);
if ($rs) {
$ADODB_SESS_CONN->BeginTrans();
while (!$rs->EOF) {
$ref = $rs->fields[0];
$key = $rs->fields[1];
$fn($ref,$key);
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$rs->MoveNext();
}
$ADODB_SESS_CONN->CommitTrans();
}
} else {
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE sesskey = '$key'";
$rs = $ADODB_SESS_CONN->Execute($qry);
}
return $rs ? true : false;
}
function adodb_sess_gc($maxlifetime)
{
global $ADODB_SESS_DEBUG, $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
reset($ADODB_SESSION_EXPIRE_NOTIFY);
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < " . time());
$ADODB_SESS_CONN->SetFetchMode($savem);
if ($rs) {
$ADODB_SESS_CONN->BeginTrans();
while (!$rs->EOF) {
$ref = $rs->fields[0];
$key = $rs->fields[1];
$fn($ref,$key);
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$rs->MoveNext();
}
$ADODB_SESS_CONN->CommitTrans();
}
} else {
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE expiry < " . time();
$ADODB_SESS_CONN->Execute($qry);
if ($ADODB_SESS_DEBUG) ADOConnection::outp("<p><b>Garbage Collection</b>: $qry</p>");
}
// suggested by Cameron, "GaM3R" <gamr@outworld.cx>
if (defined('ADODB_SESSION_OPTIMIZE')) {
global $ADODB_SESSION_DRIVER;
switch( $ADODB_SESSION_DRIVER ) {
case 'mysql':
case 'mysqlt':
$opt_qry = 'OPTIMIZE TABLE '.$ADODB_SESSION_TBL;
break;
case 'postgresql':
case 'postgresql7':
$opt_qry = 'VACUUM '.$ADODB_SESSION_TBL;
break;
}
if (!empty($opt_qry)) {
$ADODB_SESS_CONN->Execute($opt_qry);
}
}
if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
$rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
if ($rs && !$rs->EOF) {
$dbts = reset($rs->fields);
$rs->Close();
$dbt = $ADODB_SESS_CONN->UnixTimeStamp($dbts);
$t = time();
if (abs($dbt - $t) >= ADODB_SESSION_SYNCH_SECS) {
global $HTTP_SERVER_VARS;
$msg =
__FILE__.": Server time for webserver {$HTTP_SERVER_VARS['HTTP_HOST']} not in synch with database: database=$dbt ($dbts), webserver=$t (diff=".(abs($dbt-$t)/3600)." hrs)";
error_log($msg);
if ($ADODB_SESS_DEBUG) ADOConnection::outp("<p>$msg</p>");
}
}
return true;
}
session_module_name('user');
session_set_save_handler(
"adodb_sess_open",
"adodb_sess_close",
"adodb_sess_read",
"adodb_sess_write",
"adodb_sess_destroy",
"adodb_sess_gc");
}
/* TEST SCRIPT -- UNCOMMENT */
if (0) {
GLOBAL $HTTP_SESSION_VARS;
session_start();
session_register('AVAR');
$HTTP_SESSION_VARS['AVAR'] += 1;
ADOConnection::outp( "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>",false);
}
?>

View File

@ -1,398 +0,0 @@
<?php
/*
V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version of ADODB is available at http://php.weblogs.com/adodb
======================================================================
This file provides PHP4 session management using the ADODB database
wrapper library.
Example
=======
GLOBAL $HTTP_SESSION_VARS;
include('adodb.inc.php');
include('adodb-session.php');
session_start();
session_register('AVAR');
$HTTP_SESSION_VARS['AVAR'] += 1;
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
To force non-persistent connections, call adodb_session_open first before session_start():
GLOBAL $HTTP_SESSION_VARS;
include('adodb.inc.php');
include('adodb-session.php');
adodb_sess_open(false,false,false);
session_start();
session_register('AVAR');
$HTTP_SESSION_VARS['AVAR'] += 1;
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
Installation
============
1. Create this table in your database (syntax might vary depending on your db):
create table sessions (
SESSKEY char(32) not null,
EXPIRY int(11) unsigned not null,
EXPIREREF varchar(64),
DATA text not null,
primary key (sesskey)
);
For oracle:
create table sessions (
SESSKEY char(32) not null,
EXPIRY DECIMAL(16) not null,
EXPIREREF varchar(64),
DATA varchar(4000) not null,
primary key (sesskey)
);
2. Then define the following parameters. You can either modify
this file, or define them before this file is included:
$ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';
$ADODB_SESSION_CONNECT='server to connect to';
$ADODB_SESSION_USER ='user';
$ADODB_SESSION_PWD ='password';
$ADODB_SESSION_DB ='database';
$ADODB_SESSION_TBL = 'sessions'
3. Recommended is PHP 4.0.6 or later. There are documented
session bugs in earlier versions of PHP.
4. If you want to receive notifications when a session expires, then
you can tag a session with an EXPIREREF, and before the session
record is deleted, we can call a function that will pass the EXPIREREF
as the first parameter, and the session key as the second parameter.
To do this, define a notification function, say NotifyFn:
function NotifyFn($expireref, $sesskey)
{
}
Then you need to define a global variable $ADODB_SESSION_EXPIRE_NOTIFY.
This is an array with 2 elements, the first being the name of the variable
you would like to store in the EXPIREREF field, and the 2nd is the
notification function's name.
In this example, we want to be notified when a user's session
has expired, so we store the user id in the global variable $USERID,
store this value in the EXPIREREF field:
$ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');
Then when the NotifyFn is called, we are passed the $USERID as the first
parameter, eg. NotifyFn($userid, $sesskey).
*/
if (!defined('_ADODB_LAYER')) {
include (dirname(__FILE__).'/adodb.inc.php');
}
if (!defined('ADODB_SESSION')) {
define('ADODB_SESSION',1);
/* if database time and system time is difference is greater than this, then give warning */
define('ADODB_SESSION_SYNCH_SECS',60);
/****************************************************************************************\
Global definitions
\****************************************************************************************/
GLOBAL $ADODB_SESSION_CONNECT,
$ADODB_SESSION_DRIVER,
$ADODB_SESSION_USER,
$ADODB_SESSION_PWD,
$ADODB_SESSION_DB,
$ADODB_SESS_CONN,
$ADODB_SESS_LIFE,
$ADODB_SESS_DEBUG,
$ADODB_SESSION_EXPIRE_NOTIFY,
$ADODB_SESSION_CRC;
$ADODB_SESS_LIFE = ini_get('session.gc_maxlifetime');
if ($ADODB_SESS_LIFE <= 1) {
// bug in PHP 4.0.3 pl 1 -- how about other versions?
//print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $ADODB_SESS_LIFE</h3>";
$ADODB_SESS_LIFE=1440;
}
$ADODB_SESSION_CRC = false;
//$ADODB_SESS_DEBUG = true;
//////////////////////////////////
/* SET THE FOLLOWING PARAMETERS */
//////////////////////////////////
if (empty($ADODB_SESSION_DRIVER)) {
$ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='root';
$ADODB_SESSION_PWD ='';
$ADODB_SESSION_DB ='xphplens_2';
}
if (empty($ADODB_SESSION_EXPIRE_NOTIFY)) {
$ADODB_SESSION_EXPIRE_NOTIFY = false;
}
// Made table name configurable - by David Johnson djohnson@inpro.net
if (empty($ADODB_SESSION_TBL)){
$ADODB_SESSION_TBL = 'sessions';
}
/*
$ADODB_SESS['driver'] = $ADODB_SESSION_DRIVER;
$ADODB_SESS['connect'] = $ADODB_SESSION_CONNECT;
$ADODB_SESS['user'] = $ADODB_SESSION_USER;
$ADODB_SESS['pwd'] = $ADODB_SESSION_PWD;
$ADODB_SESS['db'] = $ADODB_SESSION_DB;
$ADODB_SESS['life'] = $ADODB_SESS_LIFE;
$ADODB_SESS['debug'] = $ADODB_SESS_DEBUG;
$ADODB_SESS['debug'] = $ADODB_SESS_DEBUG;
$ADODB_SESS['table'] = $ADODB_SESS_TBL;
*/
/****************************************************************************************\
Create the connection to the database.
If $ADODB_SESS_CONN already exists, reuse that connection
\****************************************************************************************/
function adodb_sess_open($save_path, $session_name,$persist=true)
{
GLOBAL $ADODB_SESS_CONN;
if (isset($ADODB_SESS_CONN)) return true;
GLOBAL $ADODB_SESSION_CONNECT,
$ADODB_SESSION_DRIVER,
$ADODB_SESSION_USER,
$ADODB_SESSION_PWD,
$ADODB_SESSION_DB,
$ADODB_SESS_DEBUG;
// cannot use & below - do not know why...
$ADODB_SESS_CONN = ADONewConnection($ADODB_SESSION_DRIVER);
if (!empty($ADODB_SESS_DEBUG)) {
$ADODB_SESS_CONN->debug = true;
ADOConnection::outp( " conn=$ADODB_SESSION_CONNECT user=$ADODB_SESSION_USER pwd=$ADODB_SESSION_PWD db=$ADODB_SESSION_DB ");
}
if ($persist) $ok = $ADODB_SESS_CONN->PConnect($ADODB_SESSION_CONNECT,
$ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
else $ok = $ADODB_SESS_CONN->Connect($ADODB_SESSION_CONNECT,
$ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
if (!$ok) ADOConnection::outp( "<p>Session: connection failed</p>",false);
}
/****************************************************************************************\
Close the connection
\****************************************************************************************/
function adodb_sess_close()
{
global $ADODB_SESS_CONN;
if ($ADODB_SESS_CONN) $ADODB_SESS_CONN->Close();
return true;
}
/****************************************************************************************\
Slurp in the session variables and return the serialized string
\****************************************************************************************/
function adodb_sess_read($key)
{
global $ADODB_SESS_CONN,$ADODB_SESSION_TBL,$ADODB_SESSION_CRC;
$rs = $ADODB_SESS_CONN->Execute("SELECT data FROM $ADODB_SESSION_TBL WHERE sesskey = '$key' AND expiry >= " . time());
if ($rs) {
if ($rs->EOF) {
$v = '';
} else
$v = rawurldecode(reset($rs->fields));
$rs->Close();
// new optimization adodb 2.1
$ADODB_SESSION_CRC = strlen($v).crc32($v);
return $v;
}
return ''; // thx to Jorma Tuomainen, webmaster#wizactive.com
}
/****************************************************************************************\
Write the serialized data to a database.
If the data has not been modified since adodb_sess_read(), we do not write.
\****************************************************************************************/
function adodb_sess_write($key, $val)
{
global
$ADODB_SESS_CONN,
$ADODB_SESS_LIFE,
$ADODB_SESSION_TBL,
$ADODB_SESS_DEBUG,
$ADODB_SESSION_CRC,
$ADODB_SESSION_EXPIRE_NOTIFY;
$expiry = time() + $ADODB_SESS_LIFE;
// crc32 optimization since adodb 2.1
// now we only update expiry date, thx to sebastian thom in adodb 2.32
if ($ADODB_SESSION_CRC !== false && $ADODB_SESSION_CRC == strlen($val).crc32($val)) {
if ($ADODB_SESS_DEBUG) echo "<p>Session: Only updating date - crc32 not changed</p>";
$qry = "UPDATE $ADODB_SESSION_TBL SET expiry=$expiry WHERE sesskey='$key' AND expiry >= " . time();
$rs = $ADODB_SESS_CONN->Execute($qry);
return true;
}
$val = rawurlencode($val);
$arr = array('sesskey' => $key, 'expiry' => $expiry, 'data' => $val);
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
$var = reset($ADODB_SESSION_EXPIRE_NOTIFY);
global $$var;
$arr['expireref'] = $$var;
}
$rs = $ADODB_SESS_CONN->Replace($ADODB_SESSION_TBL,$arr,
'sesskey',$autoQuote = true);
if (!$rs) {
ADOConnection::outp( '<p>Session Replace: '.$ADODB_SESS_CONN->ErrorMsg().'</p>',false);
} else {
// bug in access driver (could be odbc?) means that info is not commited
// properly unless select statement executed in Win2000
if ($ADODB_SESS_CONN->databaseType == 'access')
$rs = $ADODB_SESS_CONN->Execute("select sesskey from $ADODB_SESSION_TBL WHERE sesskey='$key'");
}
return !empty($rs);
}
function adodb_sess_destroy($key)
{
global $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
reset($ADODB_SESSION_EXPIRE_NOTIFY);
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$ADODB_SESS_CONN->SetFetchMode($savem);
if ($rs) {
$ADODB_SESS_CONN->BeginTrans();
while (!$rs->EOF) {
$ref = $rs->fields[0];
$key = $rs->fields[1];
$fn($ref,$key);
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$rs->MoveNext();
}
$ADODB_SESS_CONN->CommitTrans();
}
} else {
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE sesskey = '$key'";
$rs = $ADODB_SESS_CONN->Execute($qry);
}
return $rs ? true : false;
}
function adodb_sess_gc($maxlifetime)
{
global $ADODB_SESS_DEBUG, $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
reset($ADODB_SESSION_EXPIRE_NOTIFY);
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
$rs =& $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < " . time());
$ADODB_SESS_CONN->SetFetchMode($savem);
if ($rs) {
$ADODB_SESS_CONN->BeginTrans();
while (!$rs->EOF) {
$ref = $rs->fields[0];
$key = $rs->fields[1];
$fn($ref,$key);
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$rs->MoveNext();
}
$ADODB_SESS_CONN->CommitTrans();
}
} else {
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE expiry < " . time();
$ADODB_SESS_CONN->Execute($qry);
if ($ADODB_SESS_DEBUG) ADOConnection::outp("<p><b>Garbage Collection</b>: $qry</p>");
}
// suggested by Cameron, "GaM3R" <gamr@outworld.cx>
if (defined('ADODB_SESSION_OPTIMIZE')) {
global $ADODB_SESSION_DRIVER;
switch( $ADODB_SESSION_DRIVER ) {
case 'mysql':
case 'mysqlt':
$opt_qry = 'OPTIMIZE TABLE '.$ADODB_SESSION_TBL;
break;
case 'postgresql':
case 'postgresql7':
$opt_qry = 'VACUUM '.$ADODB_SESSION_TBL;
break;
}
if (!empty($opt_qry)) {
$ADODB_SESS_CONN->Execute($opt_qry);
}
}
if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
$rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
if ($rs && !$rs->EOF) {
$dbts = reset($rs->fields);
$rs->Close();
$dbt = $ADODB_SESS_CONN->UnixTimeStamp($dbts);
$t = time();
if (abs($dbt - $t) >= ADODB_SESSION_SYNCH_SECS) {
global $HTTP_SERVER_VARS;
$msg =
__FILE__.": Server time for webserver {$HTTP_SERVER_VARS['HTTP_HOST']} not in synch with database: database=$dbt ($dbts), webserver=$t (diff=".(abs($dbt-$t)/3600)." hrs)";
error_log($msg);
if ($ADODB_SESS_DEBUG) ADOConnection::outp("<p>$msg</p>");
}
}
return true;
}
session_module_name('user');
session_set_save_handler(
"adodb_sess_open",
"adodb_sess_close",
"adodb_sess_read",
"adodb_sess_write",
"adodb_sess_destroy",
"adodb_sess_gc");
}
/* TEST SCRIPT -- UNCOMMENT */
if (0) {
GLOBAL $HTTP_SESSION_VARS;
session_start();
session_register('AVAR');
$HTTP_SESSION_VARS['AVAR'] += 1;
ADOConnection::outp( "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>",false);
}
?>

View File

@ -1,43 +0,0 @@
2003-05-03 14:20 richtl
* INSTALL, xmlschema.html: Renamed adodb-xmlschema.php to
adodb-xmlschema.inc.php in the docs.
2003-05-03 14:17 richtl
* adodb-xmlschema.inc.php, adodb-xmlschema.php: Renamed
adodb-xmlschema.php to adodb-xmlschema.inc.php to fit in with the
ADODB standard.
2003-05-03 14:16 richtl
* xmlschema.html: Fixed a doc bug in the example.
2003-05-03 14:15 richtl
* example.php, example.xml: Initial add to CVS
2003-05-03 13:46 richtl
* adodb-xmlschema.php, xmlschema.html, INSTALL, LICENSE, README,
xmlschema.dtd, docs/blank.html, docs/classtrees_xmlschema.html,
docs/elementindex.html, docs/elementindex_xmlschema.html,
docs/errors.html, docs/index.html, docs/li_xmlschema.html,
docs/packages.html, docs/media/bg_left.png,
docs/media/stylesheet.css,
docs/xmlschema/_adodb-xmlschema_php.html,
docs/xmlschema/adoSchema.html,
docs/xmlschema/package_xmlschema.html: Initial import
2003-05-03 13:46 richtl
* adodb-xmlschema.php, xmlschema.html, INSTALL, LICENSE, README,
xmlschema.dtd, docs/blank.html, docs/classtrees_xmlschema.html,
docs/elementindex.html, docs/elementindex_xmlschema.html,
docs/errors.html, docs/index.html, docs/li_xmlschema.html,
docs/packages.html, docs/media/bg_left.png,
docs/media/stylesheet.css,
docs/xmlschema/_adodb-xmlschema_php.html,
docs/xmlschema/adoSchema.html,
docs/xmlschema/package_xmlschema.html: Initial revision

View File

@ -1,8 +0,0 @@
INSTALL
To install adodb-xmlschema, simply copy the adodb-xmlschema.inc.php file into your ADODB directory.
------------------------------------------------------------------------------------------------------------------------------------
If you have any questions or comments, please email them to me at richtl@arscognita.com.
$Id$

View File

@ -1,544 +0,0 @@
adodb-xmlschema is dual licensed using BSD-Style and LGPL. Where there is any di
screpancy, the BSD-Style license will take precedence. In plain English, you do
not need to distribute your application in source code form, nor do you need to
distribute adodb-xmlschema source code, provided you follow the rest of terms o
f the BSD-style license.
Commercial use of adodb-xmlschema is encouraged. Make money and multiply!
BSD Style-License
=================
Copyright (c) 2003 ars Cognita, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this l
ist of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
Neither the name of the John Lim nor the names of its contributors may be used t
o endorse or promote products derived from this software without specific prior
written permission.
DISCLAIMER:
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WA
RRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIREC
T, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P
ROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWI
SE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE P
OSSIBILITY OF SUCH DAMAGE.
==========================================================
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -1,36 +0,0 @@
adodb-xmlschema
------------------------------------------------------------------------------------------------------------------------------------
Written by Richard Tango-Lowy.
For more information, contact richtl@arscognita.com or visit our site at www.arscognita.com.
To report bugs or comments, see the ADOdb main README file.
Introduction:
adodb-xmlschema is a class that allows the user to quickly and easily build a database on any
ADOdb-supported platform using a simple XML format.
This library is dual-licensed under a BSD-style license and under the GNU LESSER PUBLIC LICENSE.
See the LICENSE file for more information.
Features:
* Darned easy to install
* Quickly to create schemas that build on any platform supported by ADODB.
Notes:
See the INSTALL file for installation notes.
See docs/index.html for documentation, including installation, use, and tutorials.
Thanks:
Thanks to John Lim for giving us ADODB, and for the hard work that keeps it on top of things.
And particulary for the datadict code that made xmlschema possible.
And to the kind folks at PHP Documentor. Cool tool.
And to Linus. I thought the end of Amiga was the end of computing. Guess I was wrong :-)
------------------------------------------------------------------------------------------------------------------------------------
If you have any questions or comments, please email them to me at richtl@arscognita.com.
$Id$

View File

@ -1,722 +0,0 @@
<?PHP
/* ******************************************************************************
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
*******************************************************************************/
/**
* xmlschema is a class that allows the user to quickly and easily
* build a database on any ADOdb-supported platform using a simple
* XML schema.
*
* @author Richard Tango-Lowy
* @version $Revision$
* @copyright Copyright (c) 2003 ars Cognita Inc., all rights reserved
*
* @package xmlschema
*/
/**
* Include the main ADODB library
*/
if (!defined( '_ADODB_LAYER' ) ) {
require( 'adodb.inc.php' );
}
/**
* Creates a table object in ADOdb's datadict format
*
* This class stores information about a database table. As charactaristics
* of the table are loaded from the external source, methods and properties
* of this class are used to build up the table description in ADOdb's
* datadict format.
*
* @package xmlschema
* @access private
*/
class dbTable {
/**
* @var string Table name
*/
var $tableName;
/**
* @var array Field specifier: Meta-information about each field
*/
var $fieldSpec;
/**
* @var array Table options: Table-level options
*/
var $tableOpts;
/**
* @var string Field index: Keeps track of which field is currently being processed
*/
var $currentField;
/**
* Constructor. Iniitializes a new table object.
*
* @param string $name Table name
*/
function dbTable( $name ) {
$this->tableName = $name;
}
/**
* Adds a field to a table object
*
* $name is the name of the table to which the field should be added.
* $type is an ADODB datadict field type. The following field types
* are supported as of ADODB 3.40:
* - C: varchar
* - X: CLOB (character large object) or largest varchar size
* if CLOB is not supported
* - C2: Multibyte varchar
* - X2: Multibyte CLOB
* - B: BLOB (binary large object)
* - D: Date (some databases do not support this, and we return a datetime type)
* - T: Datetime or Timestamp
* - L: Integer field suitable for storing booleans (0 or 1)
* - I: Integer (mapped to I4)
* - I1: 1-byte integer
* - I2: 2-byte integer
* - I4: 4-byte integer
* - I8: 8-byte integer
* - F: Floating point number
* - N: Numeric or decimal number
*
* @param string $name Name of the table to which the field will be added.
* @param string $type ADODB datadict field type.
* @param string $size Field size
* @param array $opts Field options array
* @return array Field specifier array
*/
function addField( $name, $type, $size = NULL, $opts = NULL ) {
// Set the field index so we know where we are
$this->currentField = $name;
// Set the field type (required)
$this->fieldSpec[$name]['TYPE'] = $type;
// Set the field size (optional)
if( isset( $size ) ) {
$this->fieldSpec[$name]['SIZE'] = $size;
}
// Set the field options
if( isset( $opts ) ) $this->fieldSpec[$name]['OPTS'] = $opts;
// Return array containing field specifier
return $this->fieldSpec;
}
/**
* Adds a field option to the current field specifier
*
* This method adds a field option allowed by the ADOdb datadict
* and appends it to the given field.
*
* @param string $field Field name
* @param string $opt ADOdb field option
* @param mixed $value Field option value
* @return array Field specifier array
*/
function addFieldOpt( $field, $opt, $value = NULL ) {
// Add the option to the field specifier
if( $value === NULL ) { // No value, so add only the option
$this->fieldSpec[$field]['OPTS'][] = $opt;
} else { // Add the option and value
$this->fieldSpec[$field]['OPTS'][] = array( "$opt" => "$value" );
}
// Return array containing field specifier
return $this->fieldSpec;
}
/**
* Adds an option to the table
*
*This method takes a comma-separated list of table-level options
* and appends them to the table object.
*
* @param string $opt Table option
* @return string Option list
*/
function addTableOpt( $opt ) {
$optlist = &$this->tableOpts;
$optlist ? $optlist .= ", $opt" : $optlist = $opt;
// Return the options list
return $optlist;
}
/**
* Generates the SQL that will create the table in the database
*
* Returns SQL that will create the table represented by the object.
*
* @param object $dict ADOdb data dictionary
* @return array Array containing table creation SQL
*/
function create( $dict ) {
// Loop through the field specifier array, building the associative array for the field options
$fldarray = array();
$i = 0;
foreach( $this->fieldSpec as $field => $finfo ) {
$i++;
// Set an empty size if it isn't supplied
if( !isset( $finfo['SIZE'] ) ) $finfo['SIZE'] = '';
// Initialize the field array with the type and size
$fldarray[$i] = array( $field, $finfo['TYPE'], $finfo['SIZE'] );
// Loop through the options array and add the field options.
$opts = $finfo['OPTS'];
if( $opts ) {
foreach( $finfo['OPTS'] as $opt ) {
if( is_array( $opt ) ) { // Option has an argument.
$key = key( $opt );
$value = $opt[key( $opt ) ];
$fldarray[$i][$key] = $value;
} else { // Option doesn't have arguments
array_push( $fldarray[$i], $opt );
}
}
}
}
// Build table array
$sqlArray = $dict->CreateTableSQL( $this->tableName, $fldarray, $this->tableOpts );
// Return the array containing the SQL to create the table
return $sqlArray;
}
/**
* Destructor
*/
function destroy() {
unset( $this );
}
}
/**
* Creates an index object in ADOdb's datadict format
*
* This class stores information about a database index. As charactaristics
* of the index are loaded from the external source, methods and properties
* of this class are used to build up the index description in ADOdb's
* datadict format.
*
* @package xmlschema
* @access private
*/
class dbIndex {
/**
* @var string Index name
*/
var $indexName;
/**
* @var string Name of the table this index is attached to
*/
var $tableName;
/**
* @var array Indexed fields: Table columns included in this index
*/
var $fields;
/**
* Constructor. Initialize the index and table names.
*
* @param string $name Index name
* @param string $table Name of indexed table
*/
function dbIndex( $name, $table ) {
$this->indexName = $name;
$this->tableName = $table;
}
/**
* Adds a field to the index
*
* This method adds the specified column to an index.
*
* @param string $name Field name
* @return string Field list
*/
function addField( $name ) {
$fieldlist = &$this->fields;
$fieldlist ? $fieldlist .=" , $name" : $fieldlist = $name;
// Return the field list
return $fieldlist;
}
/**
* Generates the SQL that will create the index in the database
*
* Returns SQL that will create the index represented by the object.
*
* @param object $dict ADOdb data dictionary object
* @return array Array containing index creation SQL
*/
function create( $dict ) {
// Build table array
$sqlArray = $dict->CreateIndexSQL( $this->indexName, $this->tableName, $this->fields );
// Return the array containing the SQL to create the table
return $sqlArray;
}
/**
* Destructor
*/
function destroy() {
unset( $this );
}
}
/**
* Creates the SQL to execute a list of provided SQL queries
*
* This class compiles a list of SQL queries specified in the external file.
*
* @package xmlschema
* @access private
*/
class dbQuerySet {
/**
* @var array List of SQL queries
*/
var $querySet;
/**
* @var string String used to build of a query line by line
*/
var $query;
/**
* Constructor. Initializes the queries array
*/
function dbQuerySet() {
$this->querySet = array();
$this->query = '';
}
/**
* Appends a line to a query that is being built line by line
*
* $param string $data Line of SQL data or NULL to initialize a new query
*/
function buildQuery( $data = NULL ) {
isset( $data ) ? $this->query .= " " . trim( $data ) : $this->query = '';
}
/**
* Adds a completed query to the query list
*
* @return string SQL of added query
*/
function addQuery() {
// Push the query onto the query set array
$finishedQuery = $this->query;
array_push( $this->querySet, $finishedQuery );
// Return the query set array
return $finishedQuery;
}
/**
* Creates and returns the current query set
*
* @return array Query set
*/
function create() {
return $this->querySet;
}
/**
* Destructor
*/
function destroy() {
unset( $this );
}
}
/**
* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements
*
* This class is used to load and parse the XML file, to create an array of SQL statements
* that can be used to build a database, and to build the database using the SQL array.
*
* @package xmlschema
*/
class adoSchema {
/**
* @var array Array containing SQL queries to generate all objects
*/
var $sqlArray;
/**
* @var object XML Parser object
*/
var $xmlParser;
/**
* @var object ADOdb connection object
*/
var $dbconn;
/**
* @var string Database type (platform)
*/
var $dbType;
/**
* @var object ADOdb Data Dictionary
*/
var $dict;
/**
* @var object Temporary dbTable object
* @access private
*/
var $table;
/**
* @var object Temporary dbIndex object
* @access private
*/
var $index;
/**
* @var object Temporary dbQuerySet object
* @access private
*/
var $querySet;
/**
* @var string Current XML element
* @access private
*/
var $currentElement;
/**
* @var long Original Magic Quotes Runtime value
* @access private
*/
var $mgq;
/**
* Constructor. Initializes the xmlschema object
*
* @param object $dbconn ADOdb connection object
*/
function adoSchema( $dbconn ) {
// Initialize the environment
$this->mgq = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
$this->dbconn = &$dbconn;
$this->dbType = $dbconn->databaseType;
$this->sqlArray = array();
// Create an ADOdb dictionary object
$this->dict = NewDataDictionary( $dbconn );
}
/**
* Loads and parses an XML file
*
* This method accepts a path to an xmlschema-compliant XML file,
* loads it, parses it, and uses it to create the SQL to generate the objects
* described by the XML file.
*
* @param string $file XML file
* @return array Array of SQL queries, ready to execute
*/
function ParseSchema( $file ) {
// Create the parser
$this->xmlParser = &$xmlParser;
$xmlParser = xml_parser_create();
xml_set_object( $xmlParser, &$this );
// Initialize the XML callback functions
xml_set_element_handler( $xmlParser, "_xmlcb_startElement", "_xmlcb_endElement" );
xml_set_character_data_handler( $xmlParser, "_xmlcb_cData" );
// Open the file
if( !( $fp = fopen( $file, "r" ) ) ) {
die( "Unable to open file" );
}
// Process the file
while( $data = fread( $fp, 4096 ) ) {
if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {
die( sprint( "XML error: %s at line %d",
xml_error_string( xml_get_error_code( $xmlParser ) ),
xml_get_current_line_number( $xmlParser ) ) );
}
}
// Return the array of queries
return $this->sqlArray;
}
/**
* Loads a schema into the database
*
* Accepts an array of SQL queries generated by the parser
* and executes them.
*
* @param array $sqlArray Array of SQL statements
* @param boolean $continueOnErr Don't fail out if an error is encountered
* @return integer 0 if failed, 1 if errors, 2 if successful
*/
function ExecuteSchema( $sqlArray, $continueOnErr = TRUE ) {
$err = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );
// Return the success code
return $err;
}
/**
* XML Callback to process start elements
*
* @access private
*/
function _xmlcb_startElement( $parser, $name, $attrs ) {
$dbType = $this->dbType;
if( isset( $this->table ) ) $table = &$this->table;
if( isset( $this->index ) ) $index = &$this->index;
if( isset( $this->querySet ) ) $querySet = &$this->querySet;
$this->currentElement = $name;
// Process the element. Ignore unimportant elements.
if( in_array( trim( $name ), array( "SCHEMA", "DESCR", "COL", "CONSTRAINT" ) ) ) {
return FALSE;
}
switch( $name ) {
case "TABLE": // Table element
if( $this->supportedPlatform( $attrs['PLATFORM'] ) ) {
$this->table = new dbTable( $attrs['NAME'] );
} else {
unset( $this->table );
}
break;
case "FIELD": // Table field
if( isset( $this->table ) ) {
$fieldName = $attrs['NAME'];
$fieldType = $attrs['TYPE'];
isset( $attrs['SIZE'] ) ? $fieldSize = $attrs['SIZE'] : $fieldSize = NULL;
isset( $attrs['OPTS'] ) ? $fieldOpts = $attrs['OPTS'] : $fieldOpts = NULL;
$this->table->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );
}
break;
case "KEY": // Table field option
if( isset( $this->table ) ) {
$this->table->addFieldOpt( $this->table->currentField, 'KEY' );
}
break;
case "NOTNULL": // Table field option
if( isset( $this->table ) ) {
$this->table->addFieldOpt( $this->table->currentField, 'NOTNULL' );
}
break;
case "AUTOINCREMENT": // Table field option
if( isset( $this->table ) ) {
$this->table->addFieldOpt( $this->table->currentField, 'AUTOINCREMENT' );
}
break;
case "DEFAULT": // Table field option
if( isset( $this->table ) ) {
$this->table->addFieldOpt( $this->table->currentField, 'DEFAULT', $attrs['VALUE'] );
}
break;
case "INDEX": // Table index
if( $this->supportedPlatform( $attrs['PLATFORM'] ) ) {
$this->index = new dbIndex( $attrs['NAME'], $attrs['TABLE'] );
} else {
if( isset( $this->index ) ) unset( $this->index );
}
break;
case "SQL": // Freeform SQL queryset
if( $this->supportedPlatform( $attrs['PLATFORM'] ) ) {
$this->querySet = new dbQuerySet( $attrs );
} else {
if( isset( $this->querySet ) ) unset( $this->querySet );
}
break;
case "QUERY": // Queryset SQL query
if( isset( $this->querySet ) ) {
// Ignore this query set if a platform is specified and it's different than the
// current connection platform.
if( $this->supportedPlatform( $attrs['PLATFORM'] ) ) {
$this->querySet->buildQuery();
} else {
if( isset( $this->querySet->query ) ) unset( $this->querySet->query );
}
}
break;
default:
print "OPENING ELEMENT '$name'<BR/>\n";
}
}
/**
* XML Callback to process cDATA elements
*
* @access private
*/
function _xmlcb_cData( $parser, $data ) {
$element = &$this->currentElement;
if( trim( $data ) == "" ) return;
// Process the data depending on the element
switch( $element ) {
case "COL": // Index column
if( isset( $this->index ) ) $this->index->addField( $data );
break;
case "DESCR": // Description element
// Display the description information
if( isset( $this->table ) ) {
$name = "({$this->table->tableName}): ";
} elseif( isset( $this->index ) ) {
$name = "({$this->index->indexName}): ";
} else {
$name = "";
}
print "<LI> $name $data\n";
break;
case "QUERY": // Query SQL data
if( isset( $this->querySet ) and isset( $this->querySet->query ) ) $this->querySet->buildQuery( $data );
break;
case "CONSTRAINT": // Table constraint
if( isset( $this->table ) ) $this->table->addTableOpt( $data );
break;
default:
print "<UL><LI>CDATA ($element) $data</UL>\n";
}
}
/**
* XML Callback to process end elements
*
* @access private
*/
function _xmlcb_endElement( $parser, $name ) {
// Process the element. Ignore unimportant elements.
if( in_array( trim( $name ),
array( "SCHEMA", "DESCR", "KEY", "AUTOINCREMENT", "FIELD",
"DEFAULT", "NOTNULL", "CONSTRAINT", "COL" ) ) ) {
return FALSE;
}
switch( trim( $name ) ) {
case "TABLE": // Table element
if( isset( $this->table ) ) {
$tableSQL = $this->table->create( $this->dict );
array_push( $this->sqlArray, $tableSQL[0] );
$this->table->destroy();
}
break;
case "INDEX": // Index element
if( isset( $this->index ) ) {
$indexSQL = $this->index->create( $this->dict );
array_push( $this->sqlArray, $indexSQL[0] );
$this->index->destroy();
}
break;
case "QUERY": // Queryset element
if( isset( $this->querySet ) and isset( $this->querySet->query ) ) $this->querySet->addQuery();
break;
case "SQL": // Query SQL element
if( isset( $this->querySet ) ) {
$querySQL = $this->querySet->create();
$this->sqlArray = array_merge( $this->sqlArray, $querySQL );;
$this->querySet->destroy();
}
break;
default:
print "<LI>CLOSING $name</UL>\n";
}
}
/**
* Checks if element references a specific platform
*
* Returns TRUE is no platform is specified or if we are currently
* using the specified platform.
*
* @param string $platform Requested platform
* @return boolean TRUE if platform check succeeds
*
* @access private
*/
function supportedPlatform( $platform = NULL ) {
$dbType = $this->dbType;
$regex = "/^(\w*\|)*" . $dbType . "(\|\w*)*$/";
if( !isset( $platform ) or
preg_match( $regex, $platform ) ) {
return TRUE;
} else {
return FALSE;
}
}
/**
* Destructor
*/
function Destroy() {
xml_parser_free( $this->xmlParser );
set_magic_quotes_runtime( $this->mgq );
unset( $this );
}
}
?>

View File

@ -1,114 +0,0 @@
<H1>adodb-xmlschema</H1>
<P>Written by <a href="mailto:richtl@arscognita.com">Richard Tango-Lowy</a>.</P>
<P>For more information, contact <a href="richtl@arscognita.com">richtl@arscognita.com</a>
or visit our site at <a href="http://www.arscognita.com">www.arscognita.com</a>.</P>
<P>At the moment, you should report bugs by mailing them to me. (If I can't convince John to
make this part of ADODB :-), I'll create a project for it on SourceForge.)
<H2>Introduction</H2>
<P><B>adodb-xmlschema</B> is a class that allows the user to quickly and easily
build a database on any ADOdb-supported platform using a simple XML format.</P>
<P>This library is dual-licensed under a BSD-style license and under the <B><a href="http://opensource.org/licenses/lgpl-license.php">GNU Lesser Public License</a></B>.
See the <B>LICENSE</B> file for more information.</P>
<H2>Features</H2><UL>
<LI>Darned easy to install
<LI>Quickly to create schemas that build on any platform supported by ADODB.</UL>
<H2>Installation</H2>
<P>To install adodb-xmlschema, simply copy the <tt>adodb-xmlschema.php</tt> file into your
<B>ADODB</B> directory.</P>
<H2>Quick Start</H2>
<P>First, create an XML database schema. Let's call it "schema.xml:"</P><PRE>
&lt;?xml version="1.0"?&gt;
&lt;schema&gt;
&lt;table name="mytable"&gt;
&lt;field name="row1" type="I"&gt;
&lt;descr&gt;An integer row that's a primary key and autoincrements&lt;/descr&gt;
&lt;KEY/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;/field&gt;
&lt;field name="row2" type="C" size="16"&gt;
&lt;descr&gt;A 16 character varchar row that can't be null&lt;/descr&gt;
&lt;NOTNULL/&gt;
&lt;/field&gt;
&lt;/table&gt;
&lt;index name="myindex" table="mytable"&gt;
&lt;col&gt;row1&lt;/col&gt;
&lt;col&gt;row2&lt;/col&gt;
&lt;/index&gt;
&lt;sql&gt;
&lt;descr&gt;SQL to be executed only on specific platforms&lt;/descr&gt;
&lt;query platform="postgres|postgres7"&gt;
insert into mytable ( row1, row2 ) values ( 12, 'stuff' )
&lt;/query&gt;
&lt;query platform="mysql"&gt;
insert into mytable ( row1, row2 ) values ( 12, 'different stuff' )
&lt;/query&gt;
&lt;/sql&gt;
&lt;/schema&gt;
</PRE><P>Create a new database using the appropriate tool for your platform.
Executing the following PHP code will create the a <i>mytable</i> and <i>myindex</i>
in the database and insert two rows into <i>mytable</i>. </P><PRE>
// To build the schema, start by creating a normal ADOdb connection:
$db->NewADOConnection( 'mysql' );
$db->Connect( ... );
// Create the schema object and build the query array.
$schema = <B>new adoSchema</B>( $db );
// Build the SQL array
$sql = $schema-><B>ParseSchema</B>( "schema.xml" );
// Execute the SQL on the database
$result = $schema-><B>ExecuteSchema</B>( $sql );
// Finally, clean up after the XML parser
// (PHP won't do this for you!)
$schema-><B>Destroy</B>();
</PRE>
<H2>XML Schema Format:</H2>
<P>(See <a href="../xmlschema.dtd">ADOdb_schema.dtd</a> for the full specification)</P>
<PRE>
&lt;?xml version="1.0"?&gt;
&lt;schema&gt;
&lt;table name="tablename" platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;field name="fieldname" type="datadict_type" size="size"&gt;
&lt;KEY/&gt;
&lt;NOTNULL/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;DEFAULT value="value"/&gt;
&lt;/field&gt;
... <i>more fields</i>
&lt;/table&gt;
... <i>more tables</i>
&lt;index name="indexname" platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;col&gt;fieldname&lt;/col&gt;
... <i>more columns</i>
&lt;/index&gt;
... <i>more indices</i>
&lt;sql platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;query platform="platform1|platform2|..."&gt;SQL query&lt;/query&gt;
... <i>more queries</i>
&lt;/sql&gt;
... <i>more SQL</i>
&lt;/schema&gt;
</PRE>
<HR>
<H2>Thanks</H2>
<P>Thanks to John Lim for giving us ADODB, and for the hard work that keeps it on top of things.
And particulary for the datadict code that made xmlschema possible.</P>
<P>And to the kind folks at <a href="http://phpdoc.org">PHP Documentor</a>. Cool tool.</P>
<P>And to Linus. I thought the end of Amiga was the end of computing. Guess I was wrong :-)</P>
<HR>
<address>If you have any questions or comments, please email them to me at
<a href="mailto:richtl@arscognita.com">richtl@arscognita.com</a>.</address>
<P><TT>$Id$</TT></P>

View File

@ -1,28 +0,0 @@
<!--
IE 6 makes the page to wide with the following doctype. I accept
standards if they help me, not if they make anything even harder!
//-->
<!--<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/REC-html40/loose.dtd'>//-->
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by PhpDoc date: 'Sat, 3 May 2003 13:13:37 -0400' -->
<TITLE>Class Trees for Package xmlschema</TITLE>
<LINK REL ='stylesheet' TYPE='text/css' HREF='media/stylesheet.css' TITLE='Style'>
</HEAD>
<BODY BGCOLOR='white'>
<a name="top"><!-- --></a>
<!-- Start of Class Data -->
<H2>
Class Trees for Package xmlschema
</H2>
<SPAN class="code">Root class adoSchema</SPAN>
<code class="vardefaultsummary"><ul>
<li><a href="xmlschema/adoSchema.html">adoSchema</a></li></ul>
</code>
<div id="credit">
<hr>
Documention generated on Sat, 3 May 2003 13:13:37 -0400 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.0rc1</a>
</div>
</body>
</html>

View File

@ -1,99 +0,0 @@
<!--
IE 6 makes the page to wide with the following doctype. I accept
standards if they help me, not if they make anything even harder!
//-->
<!--<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/REC-html40/loose.dtd'>//-->
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by PhpDoc date: 'Sat, 3 May 2003 13:13:37 -0400' -->
<TITLE>Element Index</TITLE>
<LINK REL ='stylesheet' TYPE='text/css' HREF='media/stylesheet.css' TITLE='Style'>
</HEAD>
<BODY BGCOLOR='white'>
<a name="top"><!-- --></a><a name="top"></a>
<h1>Index of All Elements</h1>
<b>Indexes by package:</b><br />
<a href="elementindex_xmlschema.html">xmlschema</a><br />
<br />
<a href="elementindex.html#a">a</a>
<a href="elementindex.html#d">d</a>
<a href="elementindex.html#e">e</a>
<a href="elementindex.html#"></a>
<a href="elementindex.html#p">p</a>
<a href="elementindex.html#s">s</a>
<table>
<tr><td colspan = "2"><a name="a">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>a</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>adodb-xmlschema.php</b></td><td width="100%" align="left" valign="top">procedural page <a href="xmlschema/_adodb-xmlschema_php.html">adodb-xmlschema.php</a></td></tr>
<tr><td><b>adoSchema</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, method <a href="xmlschema/adoSchema.html#methodadoSchema">adoSchema::adoSchema()</a><br />&nbsp;&nbsp;&nbsp;&nbsp;Constructor.</td></tr>
<tr><td><b>adoSchema</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, class <a href="xmlschema/adoSchema.html">adoSchema</a><br />&nbsp;&nbsp;&nbsp;&nbsp;Loads and parses an XML file, creating an array of "ready-to-run" SQL statements</td></tr>
<tr><td colspan = "2"><a name="d">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>d</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>$dbconn</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, variable <a href="xmlschema/adoSchema.html#var$dbconn">adoSchema::$dbconn</a></td></tr>
<tr><td><b>$dbType</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, variable <a href="xmlschema/adoSchema.html#var$dbType">adoSchema::$dbType</a></td></tr>
<tr><td><b>$dict</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, variable <a href="xmlschema/adoSchema.html#var$dict">adoSchema::$dict</a></td></tr>
<tr><td><b>Destroy</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, method <a href="xmlschema/adoSchema.html#methodDestroy">adoSchema::Destroy()</a><br />&nbsp;&nbsp;&nbsp;&nbsp;Destructor</td></tr>
<tr><td colspan = "2"><a name="e">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>e</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>ExecuteSchema</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, method <a href="xmlschema/adoSchema.html#methodExecuteSchema">adoSchema::ExecuteSchema()</a><br />&nbsp;&nbsp;&nbsp;&nbsp;Loads a schema into the database</td></tr>
<tr><td colspan = "2"><a name="p">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>p</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>ParseSchema</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, method <a href="xmlschema/adoSchema.html#methodParseSchema">adoSchema::ParseSchema()</a><br />&nbsp;&nbsp;&nbsp;&nbsp;Loads and parses an XML file</td></tr>
<tr><td colspan = "2"><a name="s">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>s</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>$sqlArray</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, variable <a href="xmlschema/adoSchema.html#var$sqlArray">adoSchema::$sqlArray</a></td></tr>
<tr><td colspan = "2"><a name="x">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>x</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>$xmlParser</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, variable <a href="xmlschema/adoSchema.html#var$xmlParser">adoSchema::$xmlParser</a></td></tr>
</table>
</body>
</html>

View File

@ -1,109 +0,0 @@
<!--
IE 6 makes the page to wide with the following doctype. I accept
standards if they help me, not if they make anything even harder!
//-->
<!--<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/REC-html40/loose.dtd'>//-->
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by PhpDoc date: 'Sat, 3 May 2003 13:13:37 -0400' -->
<TITLE>Package xmlschema Element Index</TITLE>
<LINK REL ='stylesheet' TYPE='text/css' HREF='media/stylesheet.css' TITLE='Style'>
</HEAD>
<BODY BGCOLOR='white'>
<a name="top"><!-- --></a><a name="top"></a>
<h1>Element index for package xmlschema</h1>
<br />
<a href="elementindex.html"><b>Index of all elements</b></a><br />
<a href="elementindex_xmlschema.html#a">a</a>
<a href="elementindex_xmlschema.html#d">d</a>
<a href="elementindex_xmlschema.html#e">e</a>
<a href="elementindex_xmlschema.html#i">i</a>
<a href="elementindex_xmlschema.html#p">p</a>
<a href="elementindex_xmlschema.html#s">s</a>
<a href="elementindex_xmlschema.html#x">x</a>
<table>
<tr><td colspan = "2"><a name="a">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>a</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>adodb-xmlschema.php</b></td><td width="100%" align="left" valign="top">procedural page <a href="xmlschema/_adodb-xmlschema_php.html">adodb-xmlschema.php</a></td></tr>
<tr><td><b>adoSchema</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, method <a href="xmlschema/adoSchema.html#methodadoSchema">adoSchema::adoSchema()</a><br />&nbsp;&nbsp;&nbsp;&nbsp;Constructor.</td></tr>
<tr><td><b>adoSchema</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, class <a href="xmlschema/adoSchema.html">adoSchema</a><br />&nbsp;&nbsp;&nbsp;&nbsp;Loads and parses an XML file, creating an array of "ready-to-run" SQL statements</td></tr>
<tr><td colspan = "2"><a name="d">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>d</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>$dbconn</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, variable <a href="xmlschema/adoSchema.html#var$dbconn">adoSchema::$dbconn</a></td></tr>
<tr><td><b>$dbType</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, variable <a href="xmlschema/adoSchema.html#var$dbType">adoSchema::$dbType</a></td></tr>
<tr><td><b>$dict</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, variable <a href="xmlschema/adoSchema.html#var$dict">adoSchema::$dict</a></td></tr>
<tr><td><b>Destroy</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, method <a href="xmlschema/adoSchema.html#methodDestroy">adoSchema::Destroy()</a><br />&nbsp;&nbsp;&nbsp;&nbsp;Destructor</td></tr>
<tr><td colspan = "2"><a name="e">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>e</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>ExecuteSchema</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, method <a href="xmlschema/adoSchema.html#methodExecuteSchema">adoSchema::ExecuteSchema()</a><br />&nbsp;&nbsp;&nbsp;&nbsp;Loads a schema into the database</td></tr>
<tr><td colspan = "2"><a name="i">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>i</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td colspan = "2"><a name="p">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>p</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>ParseSchema</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, method <a href="xmlschema/adoSchema.html#methodParseSchema">adoSchema::ParseSchema()</a><br />&nbsp;&nbsp;&nbsp;&nbsp;Loads and parses an XML file</td></tr>
<tr><td colspan = "2"><a name="s">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>s</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>$sqlArray</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, variable <a href="xmlschema/adoSchema.html#var$sqlArray">adoSchema::$sqlArray</a></td></tr>
<tr><td colspan = "2"><a name="x">&nbsp; </a>
<a href="#top">top</a><br />
<TABLE CELLPADDING='3' CELLSPACING='0' WIDTH='100%' CLASS="border">
<TR CLASS='TableHeadingColor'>
<TD>
<FONT SIZE='+2'><B>x</B></FONT>
</TD>
</TR>
</TABLE>
</td></tr>
<tr><td><b>$xmlParser</b></td><td width="100%" align="left" valign="top">in file adodb-xmlschema.php, variable <a href="xmlschema/adoSchema.html#var$xmlParser">adoSchema::$xmlParser</a></td></tr>
</table>
</body>
</html>

View File

@ -1,20 +0,0 @@
<!--
IE 6 makes the page to wide with the following doctype. I accept
standards if they help me, not if they make anything even harder!
//-->
<!--<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/REC-html40/loose.dtd'>//-->
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by PhpDoc date: 'Sat, 3 May 2003 13:13:39 -0400' -->
<TITLE>phpDocumentor Parser Errors and Warnings</TITLE>
<LINK REL ='stylesheet' TYPE='text/css' HREF='media/stylesheet.css' TITLE='Style'>
</HEAD>
<BODY BGCOLOR='white'>
<a name="top"><!-- --></a><a href="#Post-parsing">Post-parsing</a><br />
<div id="credit">
<hr>
Documention generated on Sat, 3 May 2003 13:13:39 -0400 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.0rc1</a>
</div>
</body>
</html>

View File

@ -1,17 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by PhpDoc on Sat, 3 May 2003 13:13:37 -0400 -->
<TITLE>ADODB xmlschema Documentation</TITLE>
</HEAD>
<FRAMESET cols='220,*'>
<FRAME src='li_xmlschema.html' name='left_bottom'>
<FRAME src='xmlschema/package_xmlschema.html' name='right'>
<NOFRAMES>
<H2>Frame Alert</H2>
<P>This document is designed to be viewed using the frames feature.
If you see this message, you are using a non-frame-capable web client.</P>
</NOFRAMES>
</FRAMESET>
</HTML>

View File

@ -1,38 +0,0 @@
<!--
IE 6 makes the page to wide with the following doctype. I accept
standards if they help me, not if they make anything even harder!
//-->
<!--<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/REC-html40/loose.dtd'>//-->
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by PhpDoc date: 'Sat, 3 May 2003 13:13:37 -0400' -->
<TITLE></TITLE>
<LINK REL ='stylesheet' TYPE='text/css' HREF='media/stylesheet.css' TITLE='Style'>
<STYLE type="text/css"><!--
BODY {
background-image : url("media/bg_left.png");
background-repeat : repeat-y;
}
//--></STYLE>
</HEAD>
<BODY >
<a name="top"><!-- --></a><b>Package xmlschema</b><br />
<a href='classtrees_xmlschema.html' target='right'>Class Trees</a><br />
<a href='elementindex_xmlschema.html' target='right'>Alphabetical Element Index</a><br />
<a href="blank.html" target="right">xmlschema</a>
<H3>Files</H3>
<UL>
<LI><a class="procedural" href='xmlschema/_adodb-xmlschema_php.html' target='right'>adodb-xmlschema.php</a></LI>
</UL>
<H3>Classes</H3>
<UL>
<LI><a class="classes" href='xmlschema/adoSchema.html' target='right'>adoSchema</a></LI>
</UL>
<H3>Functions</H3>
<UL>
</UL>
<font size="-1"><a href="http://www.phpdoc.org" target="_blank">phpDocumentor v <b>1.2.0rc1</b></a></font>
</BODY>
</HTML>

View File

@ -1,94 +0,0 @@
BODY, DIV, SPAN, PRE, CODE, TD, TH
{
line-height : 140%;
font-size : 10pt;
}
A {
text-decoration : none;
}
A:link {
color : #336699;
}
A:visited {
color : #003366;
}
A:active, A:hover {
color : #6699CC;
}
A:hover {
text-decoration : underline;
}
SPAN.type {
color : #336699;
font-size : xx-small;
font-weight : normal;
}
PRE {
background-color : #EEEEEE;
padding : 10px;
border-width : 1px;
border-color : #336699;
border-style : solid;
}
HR {
color : #336699;
background-color : #336699;
border-width : 0px;
height : 1px;
filter : Alpha (opacity=100,finishopacity=0,style=1);
}
DIV.sdesc {
font-weight : bold;
background-color : #EEEEEE;
padding : 10px;
border-width : 1px;
border-color : #336699;
border-style : solid;
}
DIV.desc {
font-family : monospace;
background-color : #EEEEEE;
padding : 10px;
border-width : 1px;
border-color : #336699;
border-style : solid;
}
SPAN.code {
font-family : monospace;
}
CODE.varsummarydefault {
padding : 1px;
border-width : 1px;
border-style : dashed;
border-color : #336699;
}
UL.tute {
margin: 0px;
padding: 0px;
padding-left: 5px;
}
LI.tute {
line-height : 140%;
font-size : 10pt;
text-indent: -15px;
padding-bottom: 2px;
padding-left: 14px;
}
.small {
font-size : 9pt;
}

View File

@ -1,25 +0,0 @@
<!--
IE 6 makes the page to wide with the following doctype. I accept
standards if they help me, not if they make anything even harder!
//-->
<!--<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/REC-html40/loose.dtd'>//-->
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by PhpDoc date: 'Sat, 3 May 2003 13:13:37 -0400' -->
<TITLE></TITLE>
<LINK REL ='stylesheet' TYPE='text/css' HREF='media/stylesheet.css' TITLE='Style'>
<STYLE type="text/css"><!--
BODY {
background-image : url("media/bg_left.png");
background-repeat : repeat-y;
}
//--></STYLE>
</HEAD>
<BODY >
<a name="top"><!-- --></a><h3>Packages</h3>
<UL>
<LI><a class="package" href='li_xmlschema.html' target='left_bottom'>xmlschema</a></LI>
</UL>
</BODY>
</HTML>

View File

@ -1,111 +0,0 @@
<!--
IE 6 makes the page to wide with the following doctype. I accept
standards if they help me, not if they make anything even harder!
//-->
<!--<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/REC-html40/loose.dtd'>//-->
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by PhpDoc date: 'Sat, 3 May 2003 13:13:37 -0400' -->
<TITLE>Docs for page adodb-xmlschema.php</TITLE>
<LINK REL ='stylesheet' TYPE='text/css' HREF='../media/stylesheet.css' TITLE='Style'>
</HEAD>
<BODY BGCOLOR='white'>
<a name="top"><!-- --></a><h3><SPAN class="type">File:</SPAN> Program_Root/adodb-xmlschema.php<HR>
</h3>
<!-- ========== Info from phpDoc block ========= -->
<div class="sdesc">xmlschema is a class that allows the user to quickly and easily build a database on any ADOdb-supported platform using a simple XML schema.</div>
<UL>
<LI><b>copyright:</b> <CODE>Copyright &copy; 2003 ars Cognita Inc., all rights reserved</CODE></LI>
<LI><b>version:</b> <CODE>$revision: $</CODE></LI>
<LI><b>author:</b> <CODE>Richard Tango-Lowy</CODE></LI>
</UL>
Classes in this file:
<dl>
<dt></dt>
<dd>Creates a table object in ADOdb's datadict format</dd>
<dt></dt>
<dd>Creates an index object in ADOdb's datadict format</dd>
<dt></dt>
<dd>Creates the SQL to execute a list of provided SQL queries</dd>
<dt><a href="../xmlschema/adoSchema.html">adoSchema</a></dt>
<dd>Loads and parses an XML file, creating an array of "ready-to-run" SQL statements</dd>
</dl>
<hr>
<!-- =========== INCLUDE SUMMARY =========== -->
<A NAME='include_summary'><!-- --></A>
<H3>Include Statements Summary</H3>
<UL>
<LI><CODE><A HREF="#_adodb_inc_php">include</A></CODE> = <CODE class="varsummarydefault">"adodb.inc.php"</CODE>
<br />Include the main ADODB library
</UL>
<hr>
<!-- =========== GLOBAL VARIABLE SUMMARY =========== -->
<A NAME='global_summary'><!-- --></A>
<H3>Global Variable Summary</H3>
<UL>
</UL>
<hr>
<!-- =========== CONSTANT SUMMARY =========== -->
<A NAME='constant_summary'><!-- --></A>
<H3>Constant Summary</H3>
<UL>
</UL>
<hr>
<!-- =========== FUNCTION SUMMARY =========== -->
<A NAME='function_summary'><!-- --></A>
<H3>Function Summary</H3>
<UL>
</UL>
<hr>
<!-- ============ INCLUDE DETAIL =========== -->
<A NAME='include_detail'></A>
<H3>Include Statements Detail</H3>
<UL>
<A NAME="_adodb_inc_php"><!-- --></A>
<LI><SPAN class="code">include file:</SPAN> = <CODE class="varsummarydefault">"adodb.inc.php"</CODE> [line <span class="linenumber">31</span>]<br />
<br /><br />
<!-- ========== Info from phpDoc block ========= -->
<div class="sdesc">Include the main ADODB library</div>
<UL>
</UL>
</UL>
<hr>
<!-- ============ GLOBAL VARIABLE DETAIL =========== -->
<A NAME='global_detail'></A>
<H3>Global Variable Detail</H3>
<UL>
</UL>
<hr>
<!-- ============ CONSTANT DETAIL =========== -->
<A NAME='constant_detail'></A>
<H3>Constant Detail</H3>
<UL>
</UL>
<hr>
<!-- ============ FUNCTION DETAIL =========== -->
<A NAME='function_detail'></A>
<H3>Function Detail</H3>
<UL>
</UL>
<hr>
<div id="credit">
<hr>
Documention generated on Sat, 3 May 2003 13:13:37 -0400 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.0rc1</a>
</div>
</body>
</html>
</HTML>

View File

@ -1,235 +0,0 @@
<!--
IE 6 makes the page to wide with the following doctype. I accept
standards if they help me, not if they make anything even harder!
//-->
<!--<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/REC-html40/loose.dtd'>//-->
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by PhpDoc date: 'Sat, 3 May 2003 13:13:37 -0400' -->
<TITLE>Docs For Class adoSchema</TITLE>
<LINK REL ='stylesheet' TYPE='text/css' HREF='../media/stylesheet.css' TITLE='Style'>
</HEAD>
<BODY BGCOLOR='white'>
<a name="top"><!-- --></a><!-- Start of Class Data -->
<H3>
<SPAN class="type">Class</SPAN> adoSchema
<HR>
</H3>
[line <span class="linenumber">379</span>]<br />
<pre>
</pre>
<SPAN class="type">Location:</SPAN> Program_Root/adodb-xmlschema.php
<hr>
<!-- ========== Info from phpDoc block ========= -->
<div class="sdesc">Loads and parses an XML file, creating an array of "ready-to-run" SQL statements</div>
<div class="desc"><p>This class is used to load and parse the XML file, to create an array of SQL statements that can be used to build a database, and to build the database using the SQL array.</p></div>
<UL>
</UL>
<hr>
<!-- =========== VAR SUMMARY =========== -->
<A NAME='var_summary'><!-- --></A>
<H3>Class Variable Summary</H3>
<UL>
<!-- =========== Summary =========== -->
<LI><CODE><a href="../xmlschema/adoSchema.html#var$dbconn">$dbconn</a></CODE> = <CODE class="varsummarydefault"></CODE>
<br />
<!-- =========== Summary =========== -->
<LI><CODE><a href="../xmlschema/adoSchema.html#var$dbType">$dbType</a></CODE> = <CODE class="varsummarydefault"></CODE>
<br />
<!-- =========== Summary =========== -->
<LI><CODE><a href="../xmlschema/adoSchema.html#var$dict">$dict</a></CODE> = <CODE class="varsummarydefault"></CODE>
<br />
<!-- =========== Summary =========== -->
<LI><CODE><a href="../xmlschema/adoSchema.html#var$sqlArray">$sqlArray</a></CODE> = <CODE class="varsummarydefault"></CODE>
<br />
<!-- =========== Summary =========== -->
<LI><CODE><a href="../xmlschema/adoSchema.html#var$xmlParser">$xmlParser</a></CODE> = <CODE class="varsummarydefault"></CODE>
<br />
</UL>
<hr>
<!-- =========== INHERITED VAR SUMMARY =========== -->
<A NAME='inheritedvar_summary'><!-- --></A>
<H3>Inherited Class Variable Summary</H3>
<hr>
<!-- =========== METHOD SUMMARY =========== -->
<A NAME='method_summary'><!-- --></A>
<H3>Method Summary</H3>
<UL>
<!-- =========== Summary =========== -->
<LI><CODE><A HREF='../xmlschema/adoSchema.html#methodadoSchema'>void adoSchema()</A></CODE>
<br />Constructor.
<!-- =========== Summary =========== -->
<LI><CODE><A HREF='../xmlschema/adoSchema.html#methodDestroy'>void Destroy()</A></CODE>
<br />Destructor
<!-- =========== Summary =========== -->
<LI><CODE><A HREF='../xmlschema/adoSchema.html#methodExecuteSchema'>integer ExecuteSchema()</A></CODE>
<br />Loads a schema into the database
<!-- =========== Summary =========== -->
<LI><CODE><A HREF='../xmlschema/adoSchema.html#methodParseSchema'>array ParseSchema()</A></CODE>
<br />Loads and parses an XML file
</UL>
<!-- =========== INHERITED METHOD SUMMARY =========== -->
<A NAME='methods_inherited'><!-- --></A>
<H3>Inherited Method Summary</H3>
<hr>
<!-- ============ METHOD DETAIL =========== -->
<A NAME='method_detail'></A>
<H3>Method Detail</H3>
<UL>
<A NAME='methodadoSchema'><!-- --></A>
<LI><SPAN class="code">Constructor void adoSchema()</SPAN> [line <span class="linenumber">441</span>]
<br /><br />
<SPAN class="type">Usage:</SPAN> <SPAN class="code">adoSchema(
object
$dbconn)</SPAN>
<br /><br />
<!-- ========== Info from phpDoc block ========= -->
<div class="sdesc">Constructor.</div>
<div class="desc"><p>Initializes the xmlschema object</p></div>
<H4>Parameters</H4>
<UL>
<LI><SPAN class="code">object $dbconn</SPAN> - ADOdb connection object
</UL>
<H4>Info</H4>
<UL>
</UL>
<p class="top">[ <a href="#top">Top</a> ]</p>
<br />
<A NAME='methodDestroy'><!-- --></A>
<LI><SPAN class="code">void Destroy()</SPAN> [line <span class="linenumber">725</span>]
<br /><br />
<SPAN class="type">Usage:</SPAN> <SPAN class="code">Destroy(
)</SPAN>
<br /><br />
<!-- ========== Info from phpDoc block ========= -->
<div class="sdesc">Destructor</div>
<H4>Info</H4>
<UL>
</UL>
<p class="top">[ <a href="#top">Top</a> ]</p>
<br />
<A NAME='methodExecuteSchema'><!-- --></A>
<LI><SPAN class="code">integer ExecuteSchema()</SPAN> [line <span class="linenumber">504</span>]
<br /><br />
<SPAN class="type">Usage:</SPAN> <SPAN class="code">ExecuteSchema(
array
$sqlArray, [boolean
$continueOnErr = TRUE])</SPAN>
<br /><br />
<!-- ========== Info from phpDoc block ========= -->
<div class="sdesc">Loads a schema into the database</div>
<div class="desc"><p>Accepts an array of SQL queries generated by the parser and executes them.</p></div>
<H4>Parameters</H4>
<UL>
<LI><SPAN class="code">array $sqlArray</SPAN> - Array of SQL statements
<LI><SPAN class="code">boolean $continueOnErr</SPAN> - Don't fail out if an error is encountered
</UL>
<H4>Info</H4>
<UL>
<LI><B>return</B>: <CODE>0 if failed, 1 if errors, 2 if successful</CODE>
</UL>
<p class="top">[ <a href="#top">Top</a> ]</p>
<br />
<A NAME='methodParseSchema'><!-- --></A>
<LI><SPAN class="code">array ParseSchema()</SPAN> [line <span class="linenumber">465</span>]
<br /><br />
<SPAN class="type">Usage:</SPAN> <SPAN class="code">ParseSchema(
string
$file)</SPAN>
<br /><br />
<!-- ========== Info from phpDoc block ========= -->
<div class="sdesc">Loads and parses an XML file</div>
<div class="desc"><p>This method accepts a path to an xmlschema-compliant XML file, loads it, parses it, and uses it to create the SQL to generate the objects described by the XML file.</p></div>
<H4>Parameters</H4>
<UL>
<LI><SPAN class="code">string $file</SPAN> - XML file
</UL>
<H4>Info</H4>
<UL>
<LI><B>return</B>: <CODE>Array of SQL queries, ready to execute</CODE>
</UL>
<p class="top">[ <a href="#top">Top</a> ]</p>
<br />
</UL>
<hr>
<!-- ============ VARIABLE DETAIL =========== -->
<A NAME='variable_detail'></A>
<H3>Variable Detail</H3>
<UL>
<A NAME="var$dbconn"><!-- --></A>
<LI><SPAN class="code">$dbconn</SPAN> = <CODE class="varsummarydefault"></CODE> [line <span class="linenumber">394</span>]</LI>
<LI><b>Data type:</b> <CODE class="varsummarydefault">ADOdb</CODE></LI>
<!-- ========== Info from phpDoc block ========= -->
<UL>
<LI><b>var:</b> <CODE>connection object</CODE></LI>
</UL>
<br />
<A NAME="var$dbType"><!-- --></A>
<LI><SPAN class="code">$dbType</SPAN> = <CODE class="varsummarydefault"></CODE> [line <span class="linenumber">399</span>]</LI>
<LI><b>Data type:</b> <CODE class="varsummarydefault">string</CODE></LI>
<!-- ========== Info from phpDoc block ========= -->
<UL>
<LI><b>var:</b> <CODE>Database type (platform)</CODE></LI>
</UL>
<br />
<A NAME="var$dict"><!-- --></A>
<LI><SPAN class="code">$dict</SPAN> = <CODE class="varsummarydefault"></CODE> [line <span class="linenumber">404</span>]</LI>
<LI><b>Data type:</b> <CODE class="varsummarydefault">ADOdb</CODE></LI>
<!-- ========== Info from phpDoc block ========= -->
<UL>
<LI><b>var:</b> <CODE>Data Dictionary</CODE></LI>
</UL>
<br />
<A NAME="var$sqlArray"><!-- --></A>
<LI><SPAN class="code">$sqlArray</SPAN> = <CODE class="varsummarydefault"></CODE> [line <span class="linenumber">384</span>]</LI>
<LI><b>Data type:</b> <CODE class="varsummarydefault">array</CODE></LI>
<!-- ========== Info from phpDoc block ========= -->
<UL>
<LI><b>var:</b> <CODE>Array containing SQL queries to generate all objects</CODE></LI>
</UL>
<br />
<A NAME="var$xmlParser"><!-- --></A>
<LI><SPAN class="code">$xmlParser</SPAN> = <CODE class="varsummarydefault"></CODE> [line <span class="linenumber">389</span>]</LI>
<LI><b>Data type:</b> <CODE class="varsummarydefault">XML</CODE></LI>
<!-- ========== Info from phpDoc block ========= -->
<UL>
<LI><b>var:</b> <CODE>Parser object</CODE></LI>
</UL>
<br />
</UL>
<hr>
<div id="credit">
<hr>
Documention generated on Sat, 3 May 2003 13:13:37 -0400 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.0rc1</a>
</div>
</body>
</html>

View File

@ -1,114 +0,0 @@
<H1>adodb-xmlschema</H1>
<P>Written by <a href="mailto:richtl@arscognita.com">Richard Tango-Lowy</a>.</P>
<P>For more information, contact <a href="richtl@arscognita.com">richtl@arscognita.com</a>
or visit our site at <a href="http://www.arscognita.com">www.arscognita.com</a>.</P>
<P>At the moment, you should report bugs by mailing them to me. (If I can't convince John to
make this part of ADODB :-), I'll create a project for it on SourceForge.)
<H2>Introduction</H2>
<P><B>adodb-xmlschema</B> is a class that allows the user to quickly and easily
build a database on any ADOdb-supported platform using a simple XML format.</P>
<P>This library is dual-licensed under a BSD-style license and under the <B><a href="http://opensource.org/licenses/lgpl-license.php">GNU Lesser Public License</a></B>.
See the <B>LICENSE</B> file for more information.</P>
<H2>Features</H2><UL>
<LI>Darned easy to install
<LI>Quickly to create schemas that build on any platform supported by ADODB.</UL>
<H2>Installation</H2>
<P>To install adodb-xmlschema, simply copy the <tt>adodb-xmlschema.php</tt> file into your
<B>ADODB</B> directory.</P>
<H2>Quick Start</H2>
<P>First, create an XML database schema. Let's call it "schema.xml:"</P><PRE>
&lt;?xml version="1.0"?&gt;
&lt;schema&gt;
&lt;table name="mytable"&gt;
&lt;field name="row1" type="I"&gt;
&lt;descr&gt;An integer row that's a primary key and autoincrements&lt;/descr&gt;
&lt;KEY/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;/field&gt;
&lt;field name="row2" type="C" size="16"&gt;
&lt;descr&gt;A 16 character varchar row that can't be null&lt;/descr&gt;
&lt;NOTNULL/&gt;
&lt;/field&gt;
&lt;/table&gt;
&lt;index name="myindex" table="mytable"&gt;
&lt;col&gt;row1&lt;/col&gt;
&lt;col&gt;row2&lt;/col&gt;
&lt;/index&gt;
&lt;sql&gt;
&lt;descr&gt;SQL to be executed only on specific platforms&lt;/descr&gt;
&lt;query platform="postgres|postgres7"&gt;
insert into mytable ( row1, row2 ) values ( 12, 'stuff' )
&lt;/query&gt;
&lt;query platform="mysql"&gt;
insert into mytable ( row1, row2 ) values ( 12, 'different stuff' )
&lt;/query&gt;
&lt;/sql&gt;
&lt;/schema&gt;
</PRE><P>Create a new database using the appropriate tool for your platform.
Executing the following PHP code will create the a <i>mytable</i> and <i>myindex</i>
in the database and insert two rows into <i>mytable</i>. </P><PRE>
// To build the schema, start by creating a normal ADOdb connection:
$db->NewADOConnection( 'mysql' );
$db->Connect( ... );
// Create the schema object and build the query array.
$schema = <B>new adoSchema</B>( $db );
// Build the SQL array
$sql = $schema-><B>ParseSchema</B>( "schema.xml" );
// Execute the SQL on the database
$result = $schema-><B>ExecuteSchema</B>( $sql );
// Finally, clean up after the XML parser
// (PHP won't do this for you!)
$schema-><B>Destroy</B>();
</PRE>
<H2>XML Schema Format:</H2>
<P>(See <a href="../xmlschema.dtd">ADOdb_schema.dtd</a> for the full specification)</P>
<PRE>
&lt;?xml version="1.0"?&gt;
&lt;schema&gt;
&lt;table name="tablename" platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;field name="fieldname" type="datadict_type" size="size"&gt;
&lt;KEY/&gt;
&lt;NOTNULL/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;DEFAULT value="value"/&gt;
&lt;/field&gt;
... <i>more fields</i>
&lt;/table&gt;
... <i>more tables</i>
&lt;index name="indexname" platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;col&gt;fieldname&lt;/col&gt;
... <i>more columns</i>
&lt;/index&gt;
... <i>more indices</i>
&lt;sql platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;query platform="platform1|platform2|..."&gt;SQL query&lt;/query&gt;
... <i>more queries</i>
&lt;/sql&gt;
... <i>more SQL</i>
&lt;/schema&gt;
</PRE>
<HR>
<H2>Thanks</H2>
<P>Thanks to John Lim for giving us ADODB, and for the hard work that keeps it on top of things.
And particulary for the datadict code that made xmlschema possible.</P>
<P>And to the kind folks at <a href="http://phpdoc.org">PHP Documentor</a>. Cool tool.</P>
<P>And to Linus. I thought the end of Amiga was the end of computing. Guess I was wrong :-)</P>
<HR>
<address>If you have any questions or comments, please email them to me at
<a href="mailto:richtl@arscognita.com">richtl@arscognita.com</a>.</address>
<P><TT>$Id$</TT></P>

View File

@ -1,24 +0,0 @@
<?PHP
require( "path_to_adodb/adodb-xmlschema.inc.php" );
// To build the schema, start by creating a normal ADOdb connection:
$db = ADONewConnection( 'mysql' );
$db->Connect( 'localhost', 'someuser', '', 'schematest' );
// Create the schema object and build the query array.
$schema = new adoSchema( $db );
// Build the SQL array
$sql = $schema->ParseSchema( "example.xml" );
print "Here's the SQL to do the build:\n";
print_r( $sql );
print "\n";
// Execute the SQL on the database
$result = $schema->ExecuteSchema( $sql );
// Finally, clean up after the XML parser
// (PHP won't do this for you!)
$schema->Destroy();
?>

View File

@ -1,27 +0,0 @@
<?xml version="1.0"?>
<schema>
<table name="mytable">
<field name="row1" type="I">
<descr>An integer row that's a primary key and autoincrements</descr>
<KEY/>
<AUTOINCREMENT/>
</field>
<field name="row2" type="C" size="16">
<descr>A 16 character varchar row that can't be null</descr>
<NOTNULL/>
</field>
</table>
<index name="myindex" table="mytable">
<col>row1</col>
<col>row2</col>
</index>
<sql>
<descr>SQL to be executed only on specific platforms</descr>
<query platform="postgres|postgres7">
insert into mytable ( row1, row2 ) values ( 12, 'stuff' )
</query>
<query platform="mysql">
insert into mytable ( row1, row2 ) values ( 12, 'different stuff' )
</query>
</sql>
</schema>

View File

@ -1,31 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE adodb_schema [
<!ELEMENT schema (table*, index*, sql*)>
<!ELEMENT table (field+, constraint*, replace?, descr?)>
<!ELEMENT field ((NOTNULL|KEY|PRIMARY)?, (AUTO|AUTOINCREMENT)?, (DEFAULT|DEFDATE|DEFTIMESTAMP)?, NOQUOTE, constraint, descr?)>
<!ELEMENT descr (#CDATA)>
<!ELEMENT NOTNULL EMPTY>
<!ELEMENT KEY EMPTY>
<!ELEMENT PRIMARY EMPTY>
<!ELEMENT AUTO EMPTY>
<!ELEMENT AUTOINCREMENT EMPTY>
<!ELEMENT DEFAULT EMPTY>
<!ELEMENT DEFDATE EMPTY>
<!ELEMENT DEFTIMESTAMP EMPTY>
<!ELEMENT NOQUOTE EMPTY>
<!ELEMENT constraint (#CDATA)>
<!ATTLIST table name CDATA #REQUIRED platform CDATA #IMPLIED version CDATA #IMPLIED>
<!ATTLIST field name CDATA #REQUIRED type (C|C2|X|X2|B|D|T|L|I|F|N) #REQUIRED size CDATA #IMPLIED>
<!ATTLIST DEFAULT value CDATA #REQUIRED>
<!ELEMENT index (col+, CLUSTERED?, BITMAP?, UNIQUE?, FULLTEXT?, HASH?, descr?)>
<!ELEMENT col (#CDATA)>
<!ELEMENT CLUSTERED EMPTY>
<!ELEMENT BITMAP EMPTY>
<!ELEMENT UNIQUE EMPTY>
<!ELEMENT FULLTEXT EMPTY>
<!ELEMENT HASH EMPTY>
<!ATTLIST index name CDATA #REQUIRED table CDATA #REQUIRED>
<!ELEMENT sql (query+, descr?)>
<!ELEMENT query (#CDATA)>
<!ATTLIST sql name CDATA #IMPLIED platform CDATA #IMPLIED>
] >

View File

@ -1,116 +0,0 @@
<H1>adodb-xmlschema</H1>
<P>Written by <a href="mailto:richtl@arscognita.com">Richard Tango-Lowy</a>.</P>
<P>For more information, contact <a href="richtl@arscognita.com">richtl@arscognita.com</a>
or visit our site at <a href="http://www.arscognita.com">www.arscognita.com</a>.</P>
<P>At the moment, you should report bugs by mailing them to me. (If I can't convince John to
make this part of ADODB :-), I'll create a project for it on SourceForge.)
<H2>Introduction</H2>
<P><B>adodb-xmlschema</B> is a class that allows the user to quickly and easily
build a database using the excellent
<a href="http://php.weblogs.com/ADODB">ADODB database library</a> and a simple
XML formatted file.</P>
<P>This library is dual-licensed under a BSD-style license and under the <B><a href="http://opensource.org/licenses/lgpl-license.php">GNU Lesser Public License</a></B>.
See the <B>LICENSE</B> file for more information.</P>
<H2>Features</H2><UL>
<LI>Darned easy to install
<LI>Quickly to create schemas that build on any platform supported by ADODB.</UL>
<H2>Installation</H2>
<P>To install adodb-xmlschema, simply copy the <tt>adodb-xmlschema.inc.php</tt> file into your
<B>ADODB</B> directory.</P>
<H2>Quick Start</H2>
<P>First, create an XML database schema. Let's call it "schema.xml:"</P><PRE>
&lt;?xml version="1.0"?&gt;
&lt;schema&gt;
&lt;table name="mytable"&gt;
&lt;field name="row1" type="I"&gt;
&lt;descr&gt;An integer row that's a primary key and autoincrements&lt;/descr&gt;
&lt;KEY/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;/field&gt;
&lt;field name="row2" type="C" size="16"&gt;
&lt;descr&gt;A 16 character varchar row that can't be null&lt;/descr&gt;
&lt;NOTNULL/&gt;
&lt;/field&gt;
&lt;/table&gt;
&lt;index name="myindex" table="mytable"&gt;
&lt;col&gt;row1&lt;/col&gt;
&lt;col&gt;row2&lt;/col&gt;
&lt;/index&gt;
&lt;sql&gt;
&lt;descr&gt;SQL to be executed only on specific platforms&lt;/descr&gt;
&lt;query platform="postgres|postgres7"&gt;
insert into mytable ( row1, row2 ) values ( 12, 'stuff' )
&lt;/query&gt;
&lt;query platform="mysql"&gt;
insert into mytable ( row1, row2 ) values ( 12, 'different stuff' )
&lt;/query&gt;
&lt;/sql&gt;
&lt;/schema&gt;
</PRE><P>Create a new database using the appropriate tool for your platform.
Executing the following PHP code will create the a <i>mytable</i> and <i>myindex</i>
in the database and insert one row into <i>mytable</i> if the platform is postgres or mysql. </P><PRE>
// To build the schema, start by creating a normal ADOdb connection:
$db->NewADOConnection( 'mysql' );
$db->Connect( ... );
// Create the schema object and build the query array.
$schema = <B>new adoSchema</B>( $db );
// Build the SQL array
$sql = $schema-><B>ParseSchema</B>( "schema.xml" );
// Execute the SQL on the database
$result = $schema-><B>ExecuteSchema</B>( $sql );
// Finally, clean up after the XML parser
// (PHP won't do this for you!)
$schema-><B>Destroy</B>();
</PRE>
<H2>XML Schema Format:</H2>
<P>(See <a href="../xmlschema.dtd">ADOdb_schema.dtd</a> for the full specification)</P>
<PRE>
&lt;?xml version="1.0"?&gt;
&lt;schema&gt;
&lt;table name="tablename" platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;field name="fieldname" type="datadict_type" size="size"&gt;
&lt;KEY/&gt;
&lt;NOTNULL/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;DEFAULT value="value"/&gt;
&lt;/field&gt;
... <i>more fields</i>
&lt;/table&gt;
... <i>more tables</i>
&lt;index name="indexname" platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;col&gt;fieldname&lt;/col&gt;
... <i>more columns</i>
&lt;/index&gt;
... <i>more indices</i>
&lt;sql platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;query platform="platform1|platform2|..."&gt;SQL query&lt;/query&gt;
... <i>more queries</i>
&lt;/sql&gt;
... <i>more SQL</i>
&lt;/schema&gt;
</PRE>
<HR>
<H2>Thanks</H2>
<P>Thanks to John Lim for giving us ADODB, and for the hard work that keeps it on top of things.
And particulary for the datadict code that made xmlschema possible.</P>
<P>And to the kind folks at <a href="http://phpdoc.org">PHP Documentor</a>. Cool tool.</P>
<P>And to Linus. I thought the end of Amiga was the end of computing. Guess I was wrong :-)</P>
<HR>
<address>If you have any questions or comments, please email them to me at
<a href="mailto:richtl@arscognita.com">richtl@arscognita.com</a>.</address>
<P><TT>$Id$</TT></P>

View File

@ -10,9 +10,9 @@
* build a database on any ADOdb-supported platform using a simple
* XML schema.
*
* Last Editor: $Author$
* Last Editor: $Author: skodak $
* @author Richard Tango-Lowy & Dan Cech
* @version $Revision$
* @version $Revision: 1.14 $
*
* @package axmls
* @tutorial getting_started.pkg
@ -1209,7 +1209,7 @@ class dbQuerySet extends dbObject {
* @tutorial getting_started.pkg
*
* @author Richard Tango-Lowy & Dan Cech
* @version $Revision$
* @version $Revision: 1.14 $
*
* @package axmls
*/

View File

@ -10,9 +10,9 @@
* build a database on any ADOdb-supported platform using a simple
* XML schema.
*
* Last Editor: $Author$
* Last Editor: $Author: skodak $
* @author Richard Tango-Lowy & Dan Cech
* @version $Revision$
* @version $Revision: 1.4 $
*
* @package axmls
* @tutorial getting_started.pkg
@ -1309,7 +1309,7 @@ class dbQuerySet extends dbObject {
* @tutorial getting_started.pkg
*
* @author Richard Tango-Lowy & Dan Cech
* @version $Revision$
* @version $Revision: 1.4 $
*
* @package axmls
*/

View File

@ -1,64 +0,0 @@
<?php
// Session Encryption by Ari Kuorikoski <ari.kuorikoski@finebyte.com>
class MD5Crypt{
function keyED($txt,$encrypt_key)
{
$encrypt_key = md5($encrypt_key);
$ctr=0;
$tmp = "";
for ($i=0;$i<strlen($txt);$i++){
if ($ctr==strlen($encrypt_key)) $ctr=0;
$tmp.= substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1);
$ctr++;
}
return $tmp;
}
function Encrypt($txt,$key)
{
srand((double)microtime()*1000000);
$encrypt_key = md5(rand(0,32000));
$ctr=0;
$tmp = "";
for ($i=0;$i<strlen($txt);$i++)
{
if ($ctr==strlen($encrypt_key)) $ctr=0;
$tmp.= substr($encrypt_key,$ctr,1) .
(substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1));
$ctr++;
}
return base64_encode($this->keyED($tmp,$key));
}
function Decrypt($txt,$key)
{
$txt = $this->keyED(base64_decode($txt),$key);
$tmp = "";
for ($i=0;$i<strlen($txt);$i++){
$md5 = substr($txt,$i,1);
$i++;
$tmp.= (substr($txt,$i,1) ^ $md5);
}
return $tmp;
}
function RandPass()
{
$randomPassword = "";
srand((double)microtime()*1000000);
for($i=0;$i<8;$i++)
{
$randnumber = rand(48,120);
while (($randnumber >= 58 && $randnumber <= 64) || ($randnumber >= 91 && $randnumber <= 96))
{
$randnumber = rand(48,120);
}
$randomPassword .= chr($randnumber);
}
return $randomPassword;
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -1,551 +0,0 @@
<html>
<head>
<title>ADODB Data Dictionary Manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
body, td {
/*font-family: Arial, Helvetica, sans-serif;*/
font-size: 11pt;
}
pre {
font-size: 9pt;
}
.toplink {
font-size: 8pt;
}
</style>
</head>
<body bgcolor="#FFFFFF">
<h2>ADOdb Data Dictionary Library for PHP</h2>
<p>V4.20 22 Feb 2004 (c) 2000-2004 John Lim (<a href="mailto:jlim#natsoft.com.my">jlim#natsoft.com.my</a>).<br> AXMLS (c) 2004 ars Cognita, Inc</p>
<p><font size="1">This software is dual licensed using BSD-Style and LGPL. This means you can use it in compiled proprietary and commercial products.</font></p>
<p>Useful ADOdb links: <a href=http://php.weblogs.com/adodb?dd=1>Download</a> &nbsp; <a href=http://php.weblogs.com/adodb_manual?dd=1>Other Docs</a></p>
<p>This documentation describes a PHP class library to automate the creation of tables,
indexes and foreign key constraints portably for multiple databases. Richard Tango-Lowy and Dan Cech
have been kind enough to contribute <a href=#xmlschema>AXMLS</a>, an XML schema system for defining databases.</p>
<p>Currently the following databases are supported:</p>
<p>
<b>Well-tested:</b> PostgreSQL, MySQL, Oracle, MSSQL.<br />
<b>Beta-quality:</b> DB2, Informix, Sybase, Interbase, Firebird.<br />
<b>Alpha-quality:</b> MS Access (does not support DEFAULT values) and generic ODBC.
</p>
<h3>Example Usage</h3>
<pre>
include_once('adodb.inc.php');
<font color="#006600"># First create a normal connection</font>
$db->NewADOConnection('mysql');
$db->Connect(...);
<font color="#006600"># Then create a data dictionary object, using this connection</font>
$dict = <strong>NewDataDictionary</strong>($db);
<font color="#006600"># We have a portable declarative data dictionary format in ADOdb, similar to SQL.
# Field types use 1 character codes, and fields are separated by commas.
# The following example creates three fields: "col1", "col2" and "col3":</font>
$flds = "
<font color="#663300"><strong> col1 C(32) NOTNULL DEFAULT 'abc',
col2 I DEFAULT 0,
col3 N(12.2)</strong></font>
";
<font color="#006600"># We demonstrate creating tables and indexes</font>
$sqlarray = $dict-><strong>CreateTableSQL</strong>($tabname, $flds, $taboptarray);
$dict-><strong>ExecuteSQLArray</strong>($sqlarray);<br>
$idxflds = 'co11, col2';
$sqlarray = $dict-><strong>CreateIndexSQL</strong>($idxname, $tabname, $idxflds);
$dict-><strong>ExecuteSQLArray</strong>($sqlarray);
</pre>
<h3>Functions</h3>
<h4>function CreateDatabase($dbname, $optionsarray=false)</h4>
<p>Create a database with the name $dbname;</p>
<h4>function CreateTableSQL($tabname, $fldarray, $taboptarray=false)</h4>
<pre>
RETURNS: an array of strings, the sql to be executed, or false
$tabname: name of table
$fldarray: string (or array) containing field info
$taboptarray: array containing table options
</pre>
<p>The new format of $fldarray uses a free text format, where each field is comma-delimited.
The first token for each field is the field name, followed by the type and optional
field size. Then optional keywords in $otheroptions:</p>
<pre> "$fieldname $type $colsize $otheroptions"</pre>
<p>The older (and still supported) format of $fldarray is a 2-dimensional array, where each row in the 1st dimension represents one field. Each row has this format:</p>
<pre> array($fieldname, $type, [,$colsize] [,$otheroptions]*)</pre>
<p>The first 2 fields must be the field name and the field type. The field type can be a portable type codes or the actual type for that database.</p>
<p>Legal portable type codes include:</p>
<pre>
C: varchar
X: Largest varchar size
XL: For Oracle, returns CLOB, otherwise same as 'X' above
C2: Multibyte varchar
X2: Multibyte varchar (largest size)
B: BLOB (binary large object)
D: Date (some databases do not support this, and we return a datetime type)
T: Datetime or Timestamp
L: Integer field suitable for storing booleans (0 or 1)
I: Integer (mapped to I4)
I1: 1-byte integer
I2: 2-byte integer
I4: 4-byte integer
I8: 8-byte integer
F: Floating point number
N: Numeric or decimal number
</pre>
<p>The $colsize field represents the size of the field. If a decimal number is used, then it is assumed that the number following the dot is the precision, so 6.2 means a number of size 6 digits and 2 decimal places. It is recommended that the default for number types be represented as a string to avoid any rounding errors.</p>
<p>The $otheroptions include the following keywords (case-insensitive):</p>
<pre>
AUTO For autoincrement number. Emulated with triggers if not available.
Sets NOTNULL also.
AUTOINCREMENT Same as auto.
KEY Primary key field. Sets NOTNULL also. Compound keys are supported.
PRIMARY Same as KEY.
DEF Synonym for DEFAULT for lazy typists.
DEFAULT The default value. Character strings are auto-quoted unless
the string begins and ends with spaces, eg ' SYSDATE '.
NOTNULL If field is not null.
DEFDATE Set default value to call function to get today's date.
DEFTIMESTAMP Set default to call function to get today's datetime.
NOQUOTE Prevents autoquoting of default string values.
CONSTRAINTS Additional constraints defined at the end of the field
definition.
</pre>
<p>The Data Dictonary accepts two formats, the older array specification:</p>
<pre>
$flds = array(
array('COLNAME', 'DECIMAL', '8.4', 'DEFAULT' => 0, 'NOTNULL'),
array('id', 'I' , 'AUTO'),
array('`MY DATE`', 'D' , 'DEFDATE'),
array('NAME', 'C' , '32', 'CONSTRAINTS' => 'FOREIGN KEY REFERENCES reftable')
);
</pre>
<p>Or the simpler declarative format:</p>
<pre>
$flds = "<font color="#660000"><strong>
COLNAME DECIMAL(8.4) DEFAULT 0 NOTNULL,
id I AUTO,
`MY DATE` D DEFDATE,
NAME C(32) CONSTRAINTS 'FOREIGN KEY REFERENCES reftable'</strong></font>
";
</pre>
<p>Note that if you have special characters in the field name (e.g. My Date), you should enclose it in back-quotes. Normally field names are not case-sensitive, but if you enclose it in back-quotes, some databases treat the names as case-sensitive, and some don't. So be careful.</p>
<p>The $taboptarray is the 3rd parameter of the CreateTableSQL function. This contains table specific settings. Legal keywords include:</p>
<ul>
<li><b>REPLACE</b><br />
Indicates that the previous table definition should be removed (dropped)together with ALL data. See first example below.
</li>
<li><b>DROP</b><br />
Drop table. Useful for removing unused tables.
</li>
<li><b>CONSTRAINTS</b><br />
Define this as the key, with the constraint as the value. See the postgresql example below.
Additional constraints defined for the whole table. You will probably need to prefix this with a comma.
</li>
</ul>
<p>Database specific table options can be defined also using the name of the database type as the array key. In the following example, <em>create the table as ISAM with MySQL, and store the table in the &quot;users&quot; tablespace if using Oracle</em>. And because we specified REPLACE, drop the table first.</p>
<pre> $taboptarray = array('mysql' => 'TYPE=ISAM', 'oci8' => 'tablespace users', 'REPLACE');</pre>
<p>You can also define foreignkey constraints. The following is syntax for postgresql:
<pre> $taboptarray = array('constraints' => ', FOREIGN KEY (col1) REFERENCES reftable (refcol)');</pre>
<h4>function DropTableSQL($tabname)</h4>
<p>Returns the SQL to drop the specified table.</p>
<h4>function ChangeTableSQL($tabname, $flds)</h4>
<p>Checks to see if table exists, if table does not exist, behaves like CreateTableSQL.
If table exists, generates appropriate ALTER TABLE MODIFY COLUMN commands if
field already exists, or ALTER TABLE ADD $column if field does not exist.</p>
<p>The class must be connected to the database for ChangeTableSQL to detect the
existence of the table. Idea and code contributed by Florian Buzin.</p>
<h4>function CreateIndexSQL($idxname, $tabname, $flds, $idxoptarray=false)</h4>
<pre>
RETURNS: an array of strings, the sql to be executed, or false
$idxname: name of index
$tabname: name of table
$flds: list of fields as a comma delimited string or an array of strings
$idxoptarray: array of index creation options
</pre>
<p>$idxoptarray is similar to $taboptarray in that index specific information can be embedded in the array. Other options include:</p>
<pre>
CLUSTERED Create clustered index (only mssql)
BITMAP Create bitmap index (only oci8)
UNIQUE Make unique index
FULLTEXT Make fulltext index (only mysql)
HASH Create hash index (only postgres)
DROP Drop legacy index
</pre>
<h4>function DropIndexSQL ($idxname, $tabname = NULL)</h4>
<p>Returns the SQL to drop the specified index.</p>
<h4>function AddColumnSQL($tabname, $flds)</h4>
<p>Add one or more columns. Not guaranteed to work under all situations.</p>
<h4>function AlterColumnSQL($tabname, $flds)</h4>
<p>Warning, not all databases support this feature.</p>
<h4>function DropColumnSQL($tabname, $flds)</h4>
<p>Drop 1 or more columns.</p>
<h4>function SetSchema($schema)</h4>
<p>Set the schema.</p>
<h4>function &amp;MetaTables()</h4>
<h4>function &amp;MetaColumns($tab, $upper=true, $schema=false)</h4>
<h4>function &amp;MetaPrimaryKeys($tab,$owner=false,$intkey=false)</h4>
<h4>function &amp;MetaIndexes($table, $primary = false, $owner = false)</h4>
<p>These functions are wrappers for the corresponding functions in the connection object. However, the table names will be autoquoted by the TableName function (see below) before being passed to the connection object.</p>
<h4>function NameQuote($name = NULL)</h4>
<p>If the provided name is quoted with backquotes (`) or contains special characters, returns the name quoted with the appropriate quote character, otherwise the name is returned unchanged.</p>
<h4>function TableName($name)</h4>
<p>The same as NameQuote, but will prepend the current schema if specified</p>
<h4>function MetaType($t,$len=-1,$fieldobj=false)</h4>
<h4>function ActualType($meta)</h4>
<p>Convert between database-independent 'Meta' and database-specific 'Actual' type codes.</p>
<h4>function ExecuteSQLArray($sqlarray, $contOnError = true)</h4>
<pre>
RETURNS: 0 if failed, 1 if executed all but with errors, 2 if executed successfully
$sqlarray: an array of strings with sql code (no semicolon at the end of string)
$contOnError: if true, then continue executing even if error occurs
</pre>
<p>Executes an array of SQL strings returned by CreateTableSQL or CreateIndexSQL.</p>
<hr />
<a name=xmlschema></a>
<h2>ADOdb XML Schema (AXMLS)</h2>
<p>This is a class contributed by Richard Tango-Lowy and Dan Cech that allows the user to quickly
and easily build a database using the excellent ADODB database library and a simple XML formatted file.
You can <a href=http://sourceforge.net/projects/adodb-xmlschema/>download the latest version of AXMLS here</a>.</p>
<h3>Quick Start</h3>
<p>First, create an XML database schema. Let's call it "schema.xml:"</p>
<pre>
&lt;?xml version="1.0"?&gt;
&lt;schema version=&quot;0.2&quot;&gt;
&lt;table name="mytable"&gt;
&lt;field name="row1" type="I"&gt;
&lt;descr&gt;An integer row that's a primary key and autoincrements&lt;/descr&gt;
&lt;KEY/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;/field&gt;
&lt;field name="row2" type="C" size="16"&gt;
&lt;descr&gt;A 16 character varchar row that can't be null&lt;/descr&gt;
&lt;NOTNULL/&gt;
&lt;/field&gt;
&lt;index name=&quot;myindex&quot;&gt;
&lt;col&gt;row1&lt;/col&gt;
&lt;col&gt;row2&lt;/col&gt;
&lt;/index&gt;
&lt;/table&gt;
&lt;sql&gt;
&lt;descr&gt;SQL to be executed only on specific platforms&lt;/descr&gt;
&lt;query platform="postgres|postgres7"&gt;
insert into mytable ( row1, row2 ) values ( 12, 'stuff' )
&lt;/query&gt;
&lt;query platform="mysql"&gt;
insert into mytable ( row1, row2 ) values ( 12, 'different stuff' )
&lt;/query&gt;
&lt;/sql&gt;
&lt;/schema&gt;
</pre>
<p>Create a new database using the appropriate tool for your platform.<br />
Executing the following PHP code will create the a <i>mytable</i> and <i>myindex</i>
in the database and insert one row into <i>mytable</i> if the platform is postgres or mysql.</p>
<pre>
include_once('/path/to/adodb.inc.php');
include_once('/path/to/adodb-xmlschema.inc.php');
<font color="#006600">// To build the schema, start by creating a normal ADOdb connection:</font>
$db->NewADOConnection( 'mysql' );
$db->Connect( ... );
<font color="#006600">// Create the schema object and build the query array.</font>
$schema = new <b>adoSchema</b>( $db );
<font color="#006600">// Optionally, set a prefix for newly-created tables. In this example
// the prefix "myprefix_" will result in a table named "myprefix_tablename".</font>
$schema-><b>SetPrefix</b>( 'myprefix_' );
<font color="#006600">// Build the SQL array</font>
$schema-><b>ParseSchema</b>( 'schema.xml' );
<font color="#006600">// Execute the SQL on the database</font>
$result = $schema-><b>ExecuteSchema</b>();
<font color="#006600">// Finally, clean up after the XML parser
// (PHP won't do this for you!)</font>
$schema-><b>Destroy</b>();
</pre>
<h3>Using AXMLS in Your
Application</h3>
<p>
There are two steps involved in using
AXMLS in your application: first,
you must create a schema, or XML representation of your
database, and second, you must create the PHP code that will
parse and execute the schema.</p>
<p>Let's begin with a schema that describes a typical, if simplistic
user management table for an application.</p>
<pre class="listing"><pre>
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;schema version=&quot;0.2&quot;&gt;
&lt;table name=&quot;users&quot;&gt;
&lt;desc&gt;A typical users table for our application.&lt;/desc&gt;
&lt;field name=&quot;userId&quot; type=&quot;I&quot;&gt;
&lt;descr&gt;A unique ID assigned to each user.&lt;/descr&gt;
&lt;KEY/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;/field&gt;
&lt;field name=&quot;userName&quot; type=&quot;C&quot; size=&quot;16&quot;&gt;&lt;NOTNULL/&gt;&lt;/field&gt;
&lt;index name=&quot;userName&quot;&gt;
&lt;descr&gt;Put a unique index on the user name&lt;/descr&gt;
&lt;col&gt;userName&lt;/col&gt;
&lt;UNIQUE/&gt;
&lt;/index&gt;
&lt;/table&gt;
&lt;sql&gt;
&lt;descr&gt;Insert some data into the users table.&lt;/descr&gt;
&lt;query&gt;insert into users (userName) values ( 'admin' )&lt;/query&gt;
&lt;query&gt;insert into users (userName) values ( 'Joe' )&lt;/query&gt;
&lt;/sql&gt;
&lt;/schema&gt;
</pre></pre>
<p>Let's take a detailed look at this schema.</p>
<p>The opening &lt;?xml version=&quot;1.0&quot;?&gt; tag is
required by XML. The &lt;schema&gt; tag
tells the parser that the enclosed markup defines an XML
schema. The version=&quot;0.2&quot; attribute sets
<em>the version of the AXMLS DTD used by the XML
schema.</em> <p>All versions of AXMLS prior
to version 1.0 have a schema version of &quot;0.1&quot;. The current
schema version is &quot;0.2&quot;.</p></p>
<pre class="listing"><pre>
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;schema version=&quot;0.2&quot;&gt;
...
&lt;/schema&gt;
</pre></pre>
<p>Next we define one or more tables. A table consists of a
fields (and other objects) enclosed by
&lt;table&gt; tags. The
name=&quot;&quot; attribute specifies the name of
the table that will be created in the database.</p>
<pre class="listing"><pre>
&lt;table name=&quot;users&quot;&gt;
&lt;desc&gt;A typical users table for our application.&lt;/desc&gt;
&lt;field name=&quot;userId&quot; type=&quot;I&quot;&gt;
&lt;descr&gt;A unique ID assigned to each user.&lt;/descr&gt;
&lt;KEY/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;/field&gt;
&lt;field name=&quot;userName&quot; type=&quot;C&quot; size=&quot;16&quot;&gt;&lt;NOTNULL/&gt;&lt;/field&gt;
&lt;/table&gt;
</pre></pre>
<p>This table is called &quot;users&quot; and has a description and
two fields. The description is optional, and is currently
only for your own information; it is not applied to the
database.</p>
<p>The first &lt;field&gt; tag will create
a field named &quot;userId&quot; of type &quot;I&quot;, or integer. (See the
ADOdb Data Dictionary
documentation for a list of valid types.) This
&lt;field&gt; tag encloses two special
field options: &lt;KEY/&gt;, which
specifies this field as a primary key, and
&lt;AUTOINCREMENT/&gt;, which specifies
that the database engine should automatically fill this
field with the next available value when a new row is
inserted.</p>
<p>The second &lt;field&gt; tag will create
a field named &quot;userName&quot; of type &quot;C&quot;, or character, and of
length 16 characters. The &lt;NOTNULL/&gt;
option specifies that this field does not allow
NULLs.</p>
<p>There are two ways to add indexes to a table. The
simplest is to mark a field with the
&lt;KEY/&gt; option as described above; a
primary key is a unique index. The second and more powerful
method uses the &lt;index&gt; tags.</p>
<pre class="listing"><pre>
&lt;table name=&quot;users&quot;&gt;
...
&lt;index name=&quot;userName&quot;&gt;
&lt;descr&gt;Put a unique index on the user name&lt;/descr&gt;
&lt;col&gt;userName&lt;/col&gt;
&lt;UNIQUE/&gt;
&lt;/index&gt;
&lt;/table&gt;
</pre></pre>
<p>The &lt;index&gt; tag specifies that an
index should be created on the enclosing table. The
name=&quot;&quot; attribute provides the name of the
index that will be created in the database. The
description, as above, is for your information only. The
&lt;col&gt; tags list each column that
will be included in the index. Finally, the
&lt;UNIQUE/&gt; tag specifies that this
will be created as a unique index.</p>
<p>Finally, AXMLS allows you to include arbitrary SQL that
will be applied to the database when the schema is
executed.</p>
<pre class="listing"><pre>
&lt;sql&gt;
&lt;descr&gt;Insert some data into the users table.&lt;/descr&gt;
&lt;query&gt;insert into users (userName) values ( 'admin' )&lt;/query&gt;
&lt;query&gt;insert into users (userName) values ( 'Joe' )&lt;/query&gt;
&lt;/sql&gt;
</pre></pre>
<p>The &lt;sql&gt; tag encloses any number
of SQL queries that you define for your own use.</p>
<p>Now that we've defined an XML schema, you need to know how to
apply it to your database. Here's a simple PHP script that shows
how to load the schema.</p>
<p><pre class="listing"><pre>
&lt;?PHP
/* You must tell the script where to find the ADOdb and
* the AXMLS libraries.
*/
require( &quot;path_to_adodb/adodb.inc.php&quot;);
require( &quot;path_to_adodb/adodb-xmlschema.inc.php&quot; );
/* Configuration information. Define the schema filename,
* RDBMS platform (see the ADODB documentation for valid
* platform names), and database connection information here.
*/
$schemaFile = 'example.xml';
$platform = 'mysql';
$dbHost = 'localhost';
$dbName = 'database';
$dbUser = 'username';
$dbPassword = 'password';
/* Start by creating a normal ADODB connection.
*/
$db = ADONewConnection( $platform );
$db-&gt;Connect( $dbHost, $dbUser, $dbPassword, $dbName );
/* Use the database connection to create a new adoSchema object.
*/
$schema = new adoSchema( $db );
/* Call ParseSchema() to build SQL from the XML schema file.
* Then call ExecuteSchema() to apply the resulting SQL to
* the database.
*/
$sql = $schema-&gt;ParseSchema( $schemaFile );
$result = $schema-&gt;ExecuteSchema();
?&gt;
</pre></pre></p>
<p>Let's look at each part of the example in turn. After you
manually create the database, there are three steps required to
load (or upgrade) your schema.</p>
<p>First, create a normal ADOdb connection. The variables
and values here should be those required to connect to your
database.</p>
<pre class="listing"><pre>
$db = ADONewConnection( 'mysql' );
$db-&gt;Connect( 'host', 'user', 'password', 'database' );
</pre></pre>
<p>Second, create the adoSchema object that load and
manipulate your schema. You must pass an ADOdb database
connection object in order to create the adoSchema
object.</p>
<pre class="listing"><pre>
$schema = new adoSchema( $db );
</pre></pre>
<p>Third, call ParseSchema() to parse the
schema and then ExecuteSchema() to apply
it to the database. You must pass
ParseSchema() the path and filename of
your schema file.</p>
<pre class="listing"><pre>
$schema-&gt;ParseSchema( $schemaFile );
$schema-&gt;ExecuteSchema();
</pre></pre>
<p>Execute the above code and then log into your database. If you've
done all this right, you should see your tables, indexes, and
SQL.</p>
<p>You can find the source files for this tutorial in the
examples directory as
tutorial_shema.xml and
tutorial.php. See the class documentation for
a more detailed description of the adoSchema methods, including
methods and schema elements that are not described in this
tutorial.</p>
<H3>XML Schema Format:</H3>
<P>(See <a href="xmlschema.dtd">xmlschema.dtd</a> for the full specification)</P>
<PRE>
&lt;?xml version="1.0"?&gt;
&lt;schema version=&quot;0.2&quot;&gt;
&lt;table name="tablename" platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;field name="fieldname" type="datadict_type" size="size"&gt;
&lt;KEY/&gt;
&lt;NOTNULL/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;DEFAULT value="value"/&gt;
&lt;/field&gt;
<i> ... more fields</i>
&lt;index name="indexname" platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;col&gt;fieldname&lt;/col&gt;
<i> ... more columns</i>
&lt;/index&gt;
<i> ... more indexes</i>
&lt;/table&gt;
<i> ... more tables</i>
&lt;sql platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;query platform="platform1|platform2|..."&gt;SQL query&lt;/query&gt;
<i> ... more queries</i>
&lt;/sql&gt;
<i> ... more SQL</i>
&lt;/schema&gt;
</pre>
<h3>Upgrading</h3>
If your schema version is older, than XSLT is used to transform the schema to the newest version.
This means that if you are using an older XML schema format, you need to have the XSLT extension installed.
If you do not want to require your users to have the XSLT extension installed, make sure you
modify your XML schema to conform to the latest version.
<hr />
<address>If you have any questions or comments, please email them to Richard at richtl#arscognita.com.
</address>
</body>
</html>

View File

@ -1,386 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ADOdb Performance Monitoring Library</title>
</head>
<body>
<h3>The ADOdb Performance Monitoring Library</h3>
<p>V4.20 22 Feb 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my)</p>
<p><font size="1">This software is dual licensed using BSD-Style and LGPL. This
means you can use it in compiled proprietary and commercial products.</font></p>
<p>Useful ADOdb links: <a href=http://php.weblogs.com/adodb?perf=1>Download</a> &nbsp; <a href=http://php.weblogs.com/adodb_manual?perf=1>Other Docs</a>
<h3>Introduction</h3>
<p>This module, part of the ADOdb package, provides both CLI and HTML interfaces
for viewing key performance indicators of your database. This is very useful
because web apps such as the popular phpMyAdmin currently do not provide effective
database health monitoring tools. The module provides the following:
<ul>
<li>A quick health check of your database server using <code>$perf->HealthCheck()</code>
or <code>$perf->HealthCheckCLI()</code>.
<li>User interface for performance monitoring, <code>$perf-&gt;UI()</code>.
This UI displays:
<ul>
<li>the health check, </li>
<li>all SQL logged and their query plans, </li>
<li>a list of all tables in the current database</li>
<li>an interface to continiously poll the server for key performance indicators
such as CPU, Hit Ratio, Disk I/O</li>
<li>a form where you can enter and run SQL interactively.</li>
</ul>
<li>Gives you an API to build database monitoring tools for a server farm, for
example calling <code>$perf->DBParameter('data cache hit ratio')</code> returns
this very important statistic in a database independant manner.
</ul>
<p>ADOdb also has the ability to log all SQL executed, using <a href=docs-adodb.htm#logsql>LogSQL</a>.
All SQL logged can be analyzed through the performance monitor <a href=#ui>UI</a>.
In the <i>View SQL</i> mode, we categorize the SQL into 3 types:
<ul>
<li><b>Suspicious SQL</b>: queries with high average execution times, and are potential
candidates for rewriting</li>
<li><b>Expensive SQL</b>: queries with high total execution times (#executions * avg
execution time). Optimizing these queries will reduce your database server
load.</li>
<li><b>Invalid SQL</b>: queries that generate errors.</li>
</ul>
<p>Each query is hyperlinked to a description of the query plan, and every PHP
script that executed that query is also shown.</p>
<p>Please note that the information presented is a very basic database health
check, and does not provide a complete overview of database performance. Although
some attempt has been made to make it work across multiple databases in the
same way, it is impossible to do so. For the health check, we do try to display
the following key database parameters for all drivers:</p>
<ul>
<li><b>data cache size</b> - The amount of memory allocated to the cache.</li>
<li><b>data cache hit ratio</b> - A measure of how effective the cache is, as a percentage.
The higher, the better.</li>
<li><b>current connections</b> - The number of sessions currently connected to the
database. </li>
</ul>
<p>You will need to connect to the database as an administrator to view most of
the parameters. </p>
<p>Code improvements as very welcome, particularly adding new database parameters
and automated tuning hints.</p><a name=usage></a>
<h3>Usage</h3>
<p>Currently, the following drivers: <em>mysql</em>, <em>postgres</em>, <em>oci8</em>,
<em>mssql</em>, <i>informix</i> and <em>db2</em> are supported. To create a
new performance monitor, call NewPerfMonitor( ) as demonstrated below: </p>
<pre>
&lt;?php
include_once('adodb.inc.php');
session_start(); <font color="#006600"># session variables required for monitoring</font>
$conn = ADONewConnection($driver);
$conn-&gt;Connect($server,$user,$pwd,$db);
$perf =&amp; NewPerfMonitor($conn);
$perf-&gt;UI($pollsecs=5);<font color="#006600"></font>
?>
</pre>
<p>It is also possible to retrieve a single database parameter:</p>
<pre>$size = $perf->DBParameter('data cache size');
</pre>
<p>
Thx to Fernando Ortiz for the informix module.
<h3>Methods</h3><a name=ui></a>
<p><font face="Courier New, Courier, mono">function <b>UI($pollsecs=5)</b></font></p>
<p>Creates a web-based user interface for performance monitoring. When you click on Poll,
server statistics will be displayed every $pollsecs seconds. See <a href="#usage">Usage</a>
above.
<p>Since 4.11, we allow users to enter and run SQL interactively via the "Run SQL" link. To disable
this for security reasons, set this constant before calling $perf->UI().
<p>
<pre>define('ADODB_PERF_NO_RUN_SQL',1);</pre>
<p>Sample output follows below:</p>
<table border=1 width=100% bgcolor=lightyellow><tr>
<td> <b><a href=http://php.weblogs.com/adodb?perf=1>ADOdb</a> Performance
Monitor</b> for localhost, db=test<br>
<font size=-1>PostgreSQL 7.3.2 on i686-pc-cygwin, compiled by GCC gcc (GCC)
3.2 20020927 (prerelease)</font></tr>
<tr><td>
<a href=#>Performance Stats</a> &nbsp; <a href=#>View SQL</a>
&nbsp; <a href=#>View Tables</a> &nbsp; <a href=#>Poll Stats</a></tr></table><table border=1 bgcolor=white><tr><td colspan=3><h3>postgres7</h3></td></tr><tr><td><b>Parameter</b></td><td><b>Value</b></td><td><b>Description</b></td></tr><tr bgcolor=#F0F0F0><td colspan=3><i>Ratios</i> &nbsp;</td></tr><tr><td>statistics collector</td><td>TRUE</td><td>Value must be TRUE to enable hit ratio statistics (<i>stats_start_collector</i>,<i>stats_row_level</i> and <i>stats_block_level</i> must be set to true in postgresql.conf)</td></tr>
<tr><td>data cache hit ratio</td><td>99.7967555299239</td><td>&nbsp;</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>IO</i> &nbsp;</td></tr><tr><td>data reads</td><td>125</td><td>&nbsp; </td></tr>
<tr><td>data writes</td><td>21.78125000000000000</td><td>Count of inserts/updates/deletes * coef</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Data Cache</i> &nbsp;</td></tr><tr><td>data cache buffers</td><td>640</td><td>Number of cache buffers. <a href=http://www.varlena.com/GeneralBits/Tidbits/perf.html#basic>Tuning</a></td></tr>
<tr><td>cache blocksize</td><td>8192</td><td>(estimate)</td></tr>
<tr><td>data cache size</td><td>5M</td><td>&nbsp;</td></tr>
<tr><td>operating system cache size</td><td>80M</td><td>(effective cache size)</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Memory Usage</i> &nbsp;</td></tr><tr><td>sort buffer size</td><td>1M</td><td>Size of sort buffer (per query)</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Connections</i> &nbsp;</td></tr><tr><td>current connections</td><td>0</td><td>&nbsp;</td></tr>
<tr><td>max connections</td><td>32</td><td>&nbsp;</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Parameters</i> &nbsp;</td></tr><tr><td>rollback buffers</td><td>8</td><td>WAL buffers</td></tr>
<tr><td>random page cost</td><td>4</td><td>Cost of doing a seek (default=4). See <a href=http://www.varlena.com/GeneralBits/Tidbits/perf.html#less>random_page_cost</a></td></tr>
</table>
<p><font face="Courier New, Courier, mono">function <b>HealthCheck</b>()</font></p>
<p>Returns database health check parameters as a HTML table. You will need to
echo or print the output of this function,</p>
<p><font face="Courier New, Courier, mono">function <b>HealthCheckCLI</b>()</font></p>
<p>Returns database health check parameters formatted for a command line interface.
You will need to echo or print the output of this function. Sample output for
mysql:</p>
<pre>
-- Ratios --
MyISAM cache hit ratio => 56.5635738832
InnoDB cache hit ratio => 0
sql cache hit ratio => 0
-- IO --
data reads => 2622
data writes => 2415.5
-- Data Cache --
MyISAM data cache size => 512K
BDB data cache size => 8388600
InnoDB data cache size => 8M
-- Memory Pools --
read buffer size => 131072
sort buffer size => 65528
table cache => 4
-- Connections --
current connections => 3
max connections => 100</pre>
<p><font face="Courier New, Courier, mono">function <b>Poll</b>($pollSecs=5)
</font>
<p> Run in infinite loop, displaying the following information every $pollSecs.
This will not work properly if output buffering is enabled.
In the example below, $pollSecs=3:
<pre>
Accumulating statistics...
Time WS-CPU% Hit% Sess Reads/s Writes/s
11:08:30 0.7 56.56 1 0.0000 0.0000
11:08:33 1.8 56.56 2 0.0000 0.0000
11:08:36 11.1 56.55 3 2.5000 0.0000
11:08:39 9.8 56.55 2 3.1121 0.0000
11:08:42 2.8 56.55 1 0.0000 0.0000
11:08:45 7.4 56.55 2 0.0000 1.5000
</pre>
<p><b>WS-CPU%</b> is the Web Server CPU load of the server that PHP is running
from (eg. the database client), and not the database. The <b>Hit%</b> is the
data cache hit ratio. <b>Sess</b> is the current number of sessions connected
to the database. If you are using persistent connections, this should not change
much. The <b>Reads/s</b> and <b>Writes/s</b> are synthetic values to give the
viewer a rough guide to I/O, and are not to be taken literally.
<p><font face="Courier New, Courier, mono">function <b>SuspiciousSQL</b>($numsql=10)</font></p>
<p>Returns SQL which have high average execution times as a HTML table. Each sql statement
is hyperlinked to a new window which details the execution plan and the scripts that execute this SQL.
<p> The number of statements returned is determined by $numsql. Data is taken from the adodb_logsql table, where the sql statements are logged when
$connection->LogSQL(true) is enabled. The adodb_logsql table is populated using <a href=docs-adodb.htm#logsql>$conn->LogSQL</a>.
<p>For Oracle, Ixora Suspicious SQL returns a list of SQL statements that are most cache intensive as a HTML table.
These are data intensive SQL statements that could benefit most from tuning.
<p><font face="Courier New, Courier, mono">function <b>ExpensiveSQL</b>($numsql=10)</font></p>
<p>Returns SQL whose total execution time (avg time * #executions) is high as a HTML table. Each sql statement
is hyperlinked to a new window which details the execution plan and the scripts that execute this SQL.
<p> The number of statements returned is determined by $numsql. Data is taken from the adodb_logsql table, where the sql statements are logged when
$connection->LogSQL(true) is enabled. The adodb_logsql table is populated using <a href=docs-adodb.htm#logsql>$conn->LogSQL</a>.
<p>For Oracle, Ixora Expensive SQL returns a list of SQL statements that are taking the most CPU load
when run.
<p><font face="Courier New, Courier, mono">function <b>InvalidSQL</b>($numsql=10)</font></p>
<p>Returns a list of invalid SQL as an HTML table.
<p>Data is taken from the adodb_logsql table, where the sql statements are logged when
$connection->LogSQL(true) is enabled.
<p><font face="Courier New, Courier, mono">function <b>Tables</b>($orderby=1)</font></p>
<p>Returns information on all tables in a database, with the first two fields
containing the table name and table size, the remaining fields depend on the
database driver. If $orderby is set to 1, it will sort by name. If $orderby
is set to 2, then it will sort by table size. Some database drivers (mssql and
mysql) will ignore the $orderby clause. For postgresql, the information is up-to-date
since the last <i>vacuum</i>. Not supported currently for db2.</p>
<h3>Raw Functions</h3>
<p>Raw functions return values without any formatting.</p>
<p><font face="Courier New, Courier, mono">function <b>DBParameter</b>($paramname)</font></p>
<p>Returns the value of a database parameter, such as $this-&gt;DBParameter(&quot;data
cache size&quot;).</p>
<p><font face="Courier New, Courier, mono">function <b>CPULoad</b>()</font></p>
<p>Returns the CPU load of the database client (NOT THE SERVER) as a percentage.
Only works for Linux and Windows. For Windows, WMI must be available.</p>
<h3>Format of $settings Property</h3>
<p> To create new database parameters, you need to understand $settings. The $settings
data structure is an associative array. Each element of the array defines a
database parameter. The key is the name of the database parameter. If no key is defined,
then it is assumed to be a section break, and the value is the name of the section break.
If this is too confusing, looking at the source code will help a lot!</p>
<p> Each database parameter is itself an array consisting of the following elements:</p>
<ol start="0">
<li> Category code, used to group related db parameters. If the category code is 'HIDE', then
the database parameter is not shown when HTML() is called. <br>
</li>
<li> either
<ol type="a">
<li>sql string to retrieve value, eg. "select value from v\$parameter where
name='db_block_size'", </li>
<li>array holding sql string and field to look for, e.g. array('show variables','table_cache');
optional 3rd parameter is the $rs-&gt;fields[$index] to use (otherwise
$index=1), and optional 4th parameter is a constant to multiply the result
with (typically 100 for percentage calculations),</li>
<li>a string prefixed by =, then a PHP method of the class is invoked, e.g.
to invoke $this->GetIndexValue(), set this array element to '=GetIndexValue',
<br>
</li>
</ol>
</li>
<li> Description of database parameter. If description begins with an =, then
it is interpreted as a method call, just as in (1c) above, taking one parameter,
the current value. E.g. '=GetIndexDescription' will invoke $this->GetIndexDescription($val).
This is useful for generating tuning suggestions. For an example, see WarnCacheRatio().</li>
</ol>
<p>Example from MySQL, table_cache database parameter:</p>
<pre>'table cache' =&gt; array('CACHE', # category code
array(&quot;show variables&quot;, 'table_cache'), # array (type 1b)
'Number of tables to keep open'), # description</pre>
<h3>Example Health Check Output</h3>
<p><a href="#db2">db2</a> <a href=#informix>informix</a> <a href="#mysql">mysql</a> <a href="#mssql">mssql</a>
<a href="#oci8">oci8</a> <a href="#postgres">postgres</a></p>
<p><a name=db2></a></p>
<table border=1 bgcolor=white>
<tr>
<td colspan=3> <h3>db2</h3></td>
</tr>
<tr>
<td><b>Parameter</b></td>
<td><b>Value</b></td>
<td><b>Description</b></td>
</tr>
<tr bgcolor=#F0F0F0>
<td colspan=3><i>Ratios</i> &nbsp;</td>
</tr>
<tr bgcolor=#FFFFFF>
<td>data cache hit ratio</td>
<td>0 &nbsp; </td>
<td>&nbsp;</td>
</tr>
<tr bgcolor=#F0F0F0>
<td colspan=3><i>Data Cache</i></td>
</tr>
<tr bgcolor=#FFFFFF>
<td>data cache buffers</td>
<td>250 &nbsp; </td>
<td>See <a href=http://www7b.boulder.ibm.com/dmdd/library/techarticle/anshum/0107anshum.html#bufferpoolsize>tuning
reference</a>.</td>
</tr>
<tr bgcolor=#FFFFFF>
<td>cache blocksize</td>
<td>4096 &nbsp; </td>
<td>&nbsp;</td>
</tr>
<tr bgcolor=#FFFFFF>
<td>data cache size</td>
<td>1000K &nbsp; </td>
<td>&nbsp;</td>
</tr>
<tr bgcolor=#F0F0F0>
<td colspan=3><i>Connections</i></td>
</tr>
<tr bgcolor=#FFFFFF>
<td>current connections</td>
<td>2 &nbsp; </td>
<td>&nbsp;</td>
</tr>
</table>
<p>&nbsp;<p>
<a name=informix></a>
<table border=1 bgcolor=white><tr><td
colspan=3><h3>informix</h3></td></tr><tr><td><b>Parameter</b></td><td><b>Val
ue</b></td><td><b>Description</b></td></tr><tr bgcolor=#F0F0F0><td
colspan=3><i>Ratios</i> &nbsp;</td></tr><tr><td>data cache hit
ratio</td><td>95.89</td><td>&nbsp;</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>IO</i> &nbsp;</td></tr><tr><td>data
reads</td><td>1883884</td><td>Page reads</td></tr>
<tr><td>data writes</td><td>1716724</td><td>Page writes</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Connections</i>
&nbsp;</td></tr><tr><td>current connections</td><td>263.0</td><td>Number of
sessions</td></tr>
</table>
<p>&nbsp;</p>
<p><a name=mysql id="mysql"></a></p><table border=1 bgcolor=white><tr><td colspan=3><h3>mysql</h3></td></tr><tr><td><b>Parameter</b></td><td><b>Value</b></td><td><b>Description</b></td></tr><tr bgcolor=#F0F0F0><td colspan=3><i>Ratios</i> &nbsp;</td></tr><tr><td>MyISAM cache hit ratio</td><td>56.5658301822</td><td><font color=red><b>Cache ratio should be at least 90%</b></font></td></tr>
<tr><td>InnoDB cache hit ratio</td><td>0</td><td><font color=red><b>Cache ratio should be at least 90%</b></font></td></tr>
<tr><td>sql cache hit ratio</td><td>0</td><td>&nbsp;</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>IO</i> &nbsp;</td></tr><tr><td>data reads</td><td>2622</td><td>Number of selects (Key_reads is not accurate)</td></tr>
<tr><td>data writes</td><td>2415.5</td><td>Number of inserts/updates/deletes * coef (Key_writes is not accurate)</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Data Cache</i> &nbsp;</td></tr><tr><td>MyISAM data cache size</td><td>512K</td><td>&nbsp;</td></tr>
<tr><td>BDB data cache size</td><td>8388600</td><td>&nbsp;</td></tr>
<tr><td>InnoDB data cache size</td><td>8M</td><td>&nbsp;</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Memory Pools</i> &nbsp;</td></tr><tr><td>read buffer size</td><td>131072</td><td>(per session)</td></tr>
<tr><td>sort buffer size</td><td>65528</td><td>Size of sort buffer (per session)</td></tr>
<tr><td>table cache</td><td>4</td><td>Number of tables to keep open</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Connections</i> &nbsp;</td></tr><tr><td>current connections</td><td>3</td><td>&nbsp;</td></tr>
<tr><td>max connections</td><td>100</td><td>&nbsp;</td></tr>
</table>
<p>&nbsp;</p>
<p><a name=mssql id="mssql"></a></p>
<table border=1 bgcolor=white><tr><td colspan=3><h3>mssql</h3></td></tr><tr><td><b>Parameter</b></td><td><b>Value</b></td><td><b>Description</b></td></tr><tr bgcolor=#F0F0F0><td colspan=3><i>Ratios</i> &nbsp;</td></tr><tr><td>data cache hit ratio</td><td>99.9999694824</td><td>&nbsp;</td></tr>
<tr><td>prepared sql hit ratio</td><td>99.7738579828</td><td>&nbsp;</td></tr>
<tr><td>adhoc sql hit ratio</td><td>98.4540169133</td><td>&nbsp;</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>IO</i> &nbsp;</td></tr><tr><td>data reads</td><td>2858</td><td>&nbsp; </td></tr>
<tr><td>data writes</td><td>1438</td><td>&nbsp; </td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Data Cache</i> &nbsp;</td></tr><tr><td>data cache size</td><td>4362</td><td>in K</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Connections</i> &nbsp;</td></tr><tr><td>current connections</td><td>14</td><td>&nbsp;</td></tr>
<tr><td>max connections</td><td>32767</td><td>&nbsp;</td></tr>
</table>
<p>&nbsp;</p>
<p><a name=oci8 id="oci8"></a></p>
<table border=1 bgcolor=white><tr><td colspan=3><h3>oci8</h3></td></tr><tr><td><b>Parameter</b></td><td><b>Value</b></td><td><b>Description</b></td></tr><tr bgcolor=#F0F0F0><td colspan=3><i>Ratios</i> &nbsp;</td></tr><tr><td>data cache hit ratio</td><td>96.98</td><td>&nbsp;</td></tr>
<tr><td>sql cache hit ratio</td><td>99.96</td><td>&nbsp;</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>IO</i> &nbsp;</td></tr><tr><td>data reads</td><td>842938</td><td>&nbsp; </td></tr>
<tr><td>data writes</td><td>16852</td><td>&nbsp; </td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Data Cache</i> &nbsp;</td></tr><tr><td>data cache buffers</td><td>3072</td><td>Number of cache buffers</td></tr>
<tr><td>data cache blocksize</td><td>8192</td><td>&nbsp;</td></tr>
<tr><td>data cache size</td><td>48M</td><td>shared_pool_size</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Memory Pools</i> &nbsp;</td></tr><tr><td>java pool size</td><td>0</td><td>java_pool_size</td></tr>
<tr><td>sort buffer size</td><td>512K</td><td>sort_area_size (per query)</td></tr>
<tr><td>user session buffer size</td><td>8M</td><td>large_pool_size</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Connections</i> &nbsp;</td></tr><tr><td>current connections</td><td>1</td><td>&nbsp;</td></tr>
<tr><td>max connections</td><td>170</td><td>&nbsp;</td></tr>
<tr><td>data cache utilization ratio</td><td>88.46</td><td>Percentage of data cache actually in use</td></tr>
<tr><td>user cache utilization ratio</td><td>91.76</td><td>Percentage of user cache (large_pool) actually in use</td></tr>
<tr><td>rollback segments</td><td>11</td><td>&nbsp;</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Transactions</i> &nbsp;</td></tr><tr><td>peak transactions</td><td>24</td><td>Taken from high-water-mark</td></tr>
<tr><td>max transactions</td><td>187</td><td>max transactions / rollback segments < 3.5 (or transactions_per_rollback_segment)</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Parameters</i> &nbsp;</td></tr><tr><td>cursor sharing</td><td>EXACT</td><td>Cursor reuse strategy. Recommended is FORCE (8i+) or SIMILAR (9i+). See <a href=http://www.praetoriate.com/oracle_tips_cursor_sharing.htm>cursor_sharing</a>.</td></tr>
<tr><td>index cache cost</td><td>0</td><td>% of indexed data blocks expected in the cache.
Recommended is 20-80. Default is 0. See <a href=http://www.dba-oracle.com/oracle_tips_cbo_part1.htm>optimizer_index_caching</a>.</td></tr>
<tr><td>random page cost</td><td>100</td><td>Recommended is 10-50 for TP, and 50 for data warehouses. Default is 100. See <a href=http://www.dba-oracle.com/oracle_tips_cost_adj.htm>optimizer_index_cost_adj</a>. </td></tr>
</table>
<h3>Suspicious SQL</h3>
<table border=1 bgcolor=white><tr><td><b>LOAD</b></td><td><b>EXECUTES</b></td><td><b>SQL_TEXT</b></td></tr>
<tr><td align=right> .73%</td><td align=right>89</td><td>select u.name, o.name, t.spare1, t.pctfree$ from sys.obj$ o, sys.user$ u, sys.tab$ t where (bitand(t.trigflag, 1048576) = 1048576) and o.obj#=t.obj# and o.owner# = u.user# select i.obj#, i.flags, u.name, o.name from sys.obj$ o, sys.user$ u, sys.ind$ i where (bitand(i.flags, 256) = 256 or bitand(i.flags, 512) = 512) and (not((i.type# = 9) and bitand(i.flags,8) = 8)) and o.obj#=i.obj# and o.owner# = u.user# </td></tr>
<tr><td align=right> .84%</td><td align=right>3</td><td>select /*+ RULE */ distinct tabs.table_name, tabs.owner , partitioned, iot_type , TEMPORARY, table_type, table_type_owner from DBA_ALL_TABLES tabs where tabs.owner = :own </td></tr>
<tr><td align=right> 3.95%</td><td align=right>6</td><td>SELECT round(count(1)*avg(buf.block_size)/1048576) FROM DBA_OBJECTS obj, V$BH bh, dba_segments seg, v$buffer_pool buf WHERE obj.object_id = bh.objd AND obj.owner != 'SYS' and obj.owner = seg.owner and obj.object_name = seg.segment_name and obj.object_type = seg.segment_type and seg.buffer_pool = buf.name and buf.name = 'DEFAULT' </td></tr>
<tr><td align=right> 4.50%</td><td align=right>6</td><td>SELECT round(count(1)*avg(tsp.block_size)/1048576) FROM DBA_OBJECTS obj, V$BH bh, dba_segments seg, dba_tablespaces tsp WHERE obj.object_id = bh.objd AND obj.owner != 'SYS' and obj.owner = seg.owner and obj.object_name = seg.segment_name and obj.object_type = seg.segment_type and seg.tablespace_name = tsp.tablespace_name </td></tr>
<tr><td align=right>57.34%</td><td align=right>9267</td><td>select t.schema, t.name, t.flags, q.name from system.aq$_queue_tables t, sys.aq$_queue_table_affinities aft, system.aq$_queues q where aft.table_objno = t.objno and aft.owner_instance = :1 and q.table_objno = t.objno and q.usage = 0 and bitand(t.flags, 4+16+32+64+128+256) = 0 for update of t.name, aft.table_objno skip locked </td></tr></table>
<h3>Expensive SQL</h3>
<table border=1 bgcolor=white><tr><td><b>LOAD</b></td><td><b>EXECUTES</b></td><td><b>SQL_TEXT</b></td></tr>
<tr><td align=right> 5.24%</td><td align=right>1</td><td>select round(sum(bytes)/1048576) from dba_segments </td></tr>
<tr><td align=right> 6.89%</td><td align=right>6</td><td>SELECT round(count(1)*avg(buf.block_size)/1048576) FROM DBA_OBJECTS obj, V$BH bh, dba_segments seg, v$buffer_pool buf WHERE obj.object_id = bh.objd AND obj.owner != 'SYS' and obj.owner = seg.owner and obj.object_name = seg.segment_name and obj.object_type = seg.segment_type and seg.buffer_pool = buf.name and buf.name = 'DEFAULT' </td></tr>
<tr><td align=right> 7.85%</td><td align=right>6</td><td>SELECT round(count(1)*avg(tsp.block_size)/1048576) FROM DBA_OBJECTS obj, V$BH bh, dba_segments seg, dba_tablespaces tsp WHERE obj.object_id = bh.objd AND obj.owner != 'SYS' and obj.owner = seg.owner and obj.object_name = seg.segment_name and obj.object_type = seg.segment_type and seg.tablespace_name = tsp.tablespace_name </td></tr>
<tr><td align=right>33.69%</td><td align=right>89</td><td>select u.name, o.name, t.spare1, t.pctfree$ from sys.obj$ o, sys.user$ u, sys.tab$ t where (bitand(t.trigflag, 1048576) = 1048576) and o.obj#=t.obj# and o.owner# = u.user# </td></tr>
<tr><td align=right>36.44%</td><td align=right>89</td><td>select i.obj#, i.flags, u.name, o.name from sys.obj$ o, sys.user$ u, sys.ind$ i where (bitand(i.flags, 256) = 256 or bitand(i.flags, 512) = 512) and (not((i.type# = 9) and bitand(i.flags,8) = 8)) and o.obj#=i.obj# and o.owner# = u.user# </td></tr></table>
<p><a name=postgres id="postgres"></a></p>
<table border=1 bgcolor=white><tr><td colspan=3><h3>postgres7</h3></td></tr><tr><td><b>Parameter</b></td><td><b>Value</b></td><td><b>Description</b></td></tr><tr bgcolor=#F0F0F0><td colspan=3><i>Ratios</i> &nbsp;</td></tr><tr><td>statistics collector</td><td>FALSE</td><td>Must be set to TRUE to enable hit ratio statistics (<i>stats_start_collector</i>,<i>stats_row_level</i> and <i>stats_block_level</i> must be set to true in postgresql.conf)</td></tr>
<tr><td>data cache hit ratio</td><td>99.9666031916603</td><td>&nbsp;</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>IO</i> &nbsp;</td></tr><tr><td>data reads</td><td>15</td><td>&nbsp; </td></tr>
<tr><td>data writes</td><td>0.000000000000000000</td><td>Count of inserts/updates/deletes * coef</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Data Cache</i> &nbsp;</td></tr><tr><td>data cache buffers</td><td>1280</td><td>Number of cache buffers. <a href=http://www.varlena.com/GeneralBits/Tidbits/perf.html#basic>Tuning</a></td></tr>
<tr><td>cache blocksize</td><td>8192</td><td>(estimate)</td></tr>
<tr><td>data cache size</td><td>10M</td><td>&nbsp;</td></tr>
<tr><td>operating system cache size</td><td>80000K</td><td>(effective cache size)</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Memory Pools</i> &nbsp;</td></tr><tr><td>sort buffer size</td><td>1M</td><td>Size of sort buffer (per query)</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Connections</i> &nbsp;</td></tr><tr><td>current connections</td><td>13</td><td>&nbsp;</td></tr>
<tr><td>max connections</td><td>32</td><td>&nbsp;</td></tr>
<tr bgcolor=#F0F0F0><td colspan=3><i>Parameters</i> &nbsp;</td></tr><tr><td>rollback buffers</td><td>8</td><td>WAL buffers</td></tr>
<tr><td>random page cost</td><td>4</td><td>Cost of doing a seek (default=4). See <a href=http://www.varlena.com/GeneralBits/Tidbits/perf.html#less>random_page_cost</a></td></tr>
</table>
</body>
</html>

View File

@ -1,213 +0,0 @@
<html>
<head>
<title>ADODB Session Management Manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<XSTYLE
body,td {font-family:Arial,Helvetica,sans-serif;font-size:11pt}
pre {font-size:9pt}
.toplink {font-size:8pt}
/>
</head>
<body bgcolor="#FFFFFF">
<h3>ADODB Session Management Manual</h3>
<p>
V4.20 22 Feb 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my)
<p> <font size=1>This software is dual licensed using BSD-Style and LGPL. This
means you can use it in compiled proprietary and commercial products. </font>
<p>Useful ADOdb links: <a href=http://php.weblogs.com/adodb>Download</a> &nbsp; <a href=http://php.weblogs.com/adodb_manual>Other Docs</a>
<h3>Introduction</h3>
<p>
We store state information specific to a user or web client in session variables. These session variables
persist throughout a session, as the user moves from page to page.
<p>
To use session variables, call session_start() at the beginning of your web page,
before your HTTP headers are sent. Then for every variable you want to keep alive
for the duration of the session, call session_register($variable_name). By default,
the session handler will keep track of the session by using a cookie. You can save objects
or arrays in session variables also.
<p>The default method of storing sessions is to store it in a file. However if
you have special needs such as you:
<ul>
<li>Have multiple web servers that need to share session info</li>
<li>Need to do special processing of each session</li>
<li>Require notification when a session expires</li>
</ul>
<p>Then the ADOdb session handler provides you with the above additional capabilities
by storing the session information as records in a database table that can be
shared across multiple servers.
<p><b>Important Upgrade Notice:</b> Since ADOdb 4.05, the session files have been moved to its own folder, adodb/session. This is a rewrite
of the session code by Ross Smith. The old session code is in adodb/session/old.
<h4>ADOdb Session Handler Features</h4>
<ul>
<li>Ability to define a notification function that is called when a session expires. Typically
used to detect session logout and release global resources.
<li>Optimization of database writes. We crc32 the session data and only perform an update
to the session data if there is a data change.
<li>Support for large amounts of session data with CLOBs (see adodb-session-clob.php). Useful
for Oracle.
<li>Support for encrypted session data, see adodb-cryptsession.inc.php. Enabling encryption
is simply a matter of including adodb-cryptsession.inc.php instead of adodb-session.inc.php.
</ul>
<h3>Setup</h3>
<p>There are 3 session management files that you can use:
<pre>
adodb-session.php : The default
adodb-session-clob.php : Use this if you are storing DATA in clobs
adodb-cryptsession.php : Use this if you want to store encrypted session data in the database
<strong>Examples</strong>
<font color=#004040>
include('adodb/adodb.inc.php');
<b> $ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='scott';
$ADODB_SESSION_PWD ='tiger';
$ADODB_SESSION_DB ='sessiondb';</b>
<b>include('adodb/session/adodb-session.php');</b>
session_start();
#
# Test session vars, the following should increment on refresh
#
$_SESSION['AVAR'] += 1;
print "&lt;p>\$_SESSION['AVAR']={$_SESSION['AVAR']}&lt;/p>";
</font>
To force non-persistent connections, call adodb_session_open first before session_start():
<font color=#004040>
include('adodb/adodb.inc.php');
<b> $ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='scott';
$ADODB_SESSION_PWD ='tiger';
$ADODB_SESSION_DB ='sessiondb';</b>
<b>include('adodb/session/adodb-session.php');
adodb_sess_open(false,false,false);</b>
session_start();
</font color=#004040>
To use a encrypted sessions, simply replace the file:
<font color=#004040>
include('adodb/adodb.inc.php');
<b> $ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='scott';
$ADODB_SESSION_PWD ='tiger';
$ADODB_SESSION_DB ='sessiondb';
include('adodb/session/adodb-cryptsession.php');</b>
session_start();
</font>
And the same technique for adodb-session-clob.php:
<font color=#004040>
include('adodb/adodb.inc.php');
<b> $ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='scott';
$ADODB_SESSION_PWD ='tiger';
$ADODB_SESSION_DB ='sessiondb';
include('adodb/session/adodb-session-clob.php');</b>
session_start();
</font>
<h4>Installation</h4>
1. Create this table in your database (syntax might vary depending on your db):
<a name=sessiontab></a> <font color=#004040>
create table sessions (
SESSKEY char(32) not null,
EXPIRY int(11) unsigned not null,
EXPIREREF varchar(64),
DATA text not null,
primary key (sesskey)
);</font>
For the adodb-session-clob.php version, create this:
<font color=#004040>
create table sessions (
SESSKEY char(32) not null,
EXPIRY int(11) unsigned not null,
EXPIREREF varchar(64),
DATA CLOB,
primary key (sesskey)
);</font>
2. Then define the following parameters. You can either modify
this file, or define them before this file is included:
<font color=#004040>
$ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';
$ADODB_SESSION_CONNECT='server to connect to';
$ADODB_SESSION_USER ='user';
$ADODB_SESSION_PWD ='password';
$ADODB_SESSION_DB ='database';
$ADODB_SESSION_TBL = 'sessions'; # setting this is optional
</font>
When the session is created, $<b>ADODB_SESS_CONN</b> holds the connection object.
3. Recommended is PHP 4.0.6 or later. There are documented session bugs
in earlier versions of PHP.
</pre>
<h3>Notifications</h3>
<p>If you want to receive notification when a session expires, then
tag the session record with a <a href="#sessiontab">EXPIREREF</a> tag (see the
definition of the sessions table above). Before any session record is deleted,
ADOdb will call a notification function, passing in the EXPIREREF.
<p>
When a session is first created, we check a global variable $ADODB_SESSION_EXPIRE_NOTIFY.
This is an array with 2 elements, the first being the name of the session variable
you would like to store in the EXPIREREF field, and the 2nd is the
notification function's name.
<p>
Suppose we want to be notified when a user's session
has expired, based on the userid. The user id in the global session variable $USERID.
The function name is 'NotifyFn'. So we define:
<pre> <font color=#004040>
$ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');
</font></pre>
And when the NotifyFn is called (when the session expires), we pass the $USERID
as the first parameter, eg. NotifyFn($userid, $sesskey). The session key (which is
the primary key of the record in the sessions table) is the 2nd parameter.
<p>
Here is an example of a Notification function that deletes some records in the database
and temporary files:
<pre><font color=#004040>
function NotifyFn($expireref, $sesskey)
{
global $ADODB_SESS_CONN; # the session connection object
$user = $ADODB_SESS_CONN->qstr($expireref);
$ADODB_SESS_CONN->Execute("delete from shopping_cart where user=$user");
system("rm /work/tmpfiles/$expireref/*");
}</font>
</pre>
<p>
<p>
NOTE: If you want to change the EXPIREREF after the session record has been
created, you will need to modify any session variable to force a database
record update.
<h4>Compression/Encryption Schemes</h4>
Since ADOdb 4.05, thanks to Ross Smith, multiple encryption and compression schemes are supported.
Currently, supported:
<pre>
MD5Crypt (crypt.inc.php)
MCrypt
Secure (Horde's emulation of MCrypt, if MCrypt module is not available.)
GZip
BZip2
</pre>
These are stackable. E.g.
<pre>
ADODB_Session::filter(new ADODB_Compress_Bzip2());
ADODB_Session::filter(new ADODB_Encrypt_MD5());
</pre>
will compress and then encrypt the record in the database.
<p>
Also see the <a href=docs-adodb.htm>core ADOdb documentation</a>.
</body>
</html>

View File

@ -1,413 +0,0 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Martin Jansen <mj@php.net>
// | Richard Tango-Lowy <richtl@arscognita.com> |
// +----------------------------------------------------------------------+
//
// $Id$
//
require_once 'Auth/Container.php';
require_once 'adodb.inc.php';
require_once 'adodb-pear.inc.php';
require_once 'adodb-errorpear.inc.php';
/**
* Storage driver for fetching login data from a database using ADOdb-PHP.
*
* This storage driver can use all databases which are supported
* by the ADBdb DB abstraction layer to fetch login data.
* See http://php.weblogs.com/adodb for information on ADOdb.
* NOTE: The ADOdb directory MUST be in your PHP include_path!
*
* @author Richard Tango-Lowy <richtl@arscognita.com>
* @package Auth
* @version $Revision$
*/
class Auth_Container_ADOdb extends Auth_Container
{
/**
* Additional options for the storage container
* @var array
*/
var $options = array();
/**
* DB object
* @var object
*/
var $db = null;
var $dsn = '';
/**
* User that is currently selected from the DB.
* @var string
*/
var $activeUser = '';
// {{{ Constructor
/**
* Constructor of the container class
*
* Initate connection to the database via PEAR::ADOdb
*
* @param string Connection data or DB object
* @return object Returns an error object if something went wrong
*/
function Auth_Container_ADOdb($dsn)
{
$this->_setDefaults();
if (is_array($dsn)) {
$this->_parseOptions($dsn);
if (empty($this->options['dsn'])) {
PEAR::raiseError('No connection parameters specified!');
}
} else {
// Extract db_type from dsn string.
$this->options['dsn'] = $dsn;
}
}
// }}}
// {{{ _connect()
/**
* Connect to database by using the given DSN string
*
* @access private
* @param string DSN string
* @return mixed Object on error, otherwise bool
*/
function _connect($dsn)
{
if (is_string($dsn) || is_array($dsn)) {
if(!$this->db) {
$this->db = &ADONewConnection($dsn);
if( $err = ADODB_Pear_error() ) {
return PEAR::raiseError($err);
}
}
} else {
return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
41,
PEAR_ERROR_RETURN,
null,
null
);
}
if(!$this->db) {
return PEAR::raiseError(ADODB_Pear_error());
} else {
return true;
}
}
// }}}
// {{{ _prepare()
/**
* Prepare database connection
*
* This function checks if we have already opened a connection to
* the database. If that's not the case, a new connection is opened.
*
* @access private
* @return mixed True or a DB error object.
*/
function _prepare()
{
if(!$this->db) {
$res = $this->_connect($this->options['dsn']);
}
return true;
}
// }}}
// {{{ query()
/**
* Prepare query to the database
*
* This function checks if we have already opened a connection to
* the database. If that's not the case, a new connection is opened.
* After that the query is passed to the database.
*
* @access public
* @param string Query string
* @return mixed a DB_result object or DB_OK on success, a DB
* or PEAR error on failure
*/
function query($query)
{
$err = $this->_prepare();
if ($err !== true) {
return $err;
}
return $this->db->query($query);
}
// }}}
// {{{ _setDefaults()
/**
* Set some default options
*
* @access private
* @return void
*/
function _setDefaults()
{
$this->options['db_type'] = 'mysql';
$this->options['table'] = 'auth';
$this->options['usernamecol'] = 'username';
$this->options['passwordcol'] = 'password';
$this->options['dsn'] = '';
$this->options['db_fields'] = '';
$this->options['cryptType'] = 'md5';
}
// }}}
// {{{ _parseOptions()
/**
* Parse options passed to the container class
*
* @access private
* @param array
*/
function _parseOptions($array)
{
foreach ($array as $key => $value) {
if (isset($this->options[$key])) {
$this->options[$key] = $value;
}
}
/* Include additional fields if they exist */
if(!empty($this->options['db_fields'])){
if(is_array($this->options['db_fields'])){
$this->options['db_fields'] = join($this->options['db_fields'], ', ');
}
$this->options['db_fields'] = ', '.$this->options['db_fields'];
}
}
// }}}
// {{{ fetchData()
/**
* Get user information from database
*
* This function uses the given username to fetch
* the corresponding login data from the database
* table. If an account that matches the passed username
* and password is found, the function returns true.
* Otherwise it returns false.
*
* @param string Username
* @param string Password
* @return mixed Error object or boolean
*/
function fetchData($username, $password)
{
// Prepare for a database query
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
}
// Find if db_fields contains a *, i so assume all col are selected
if(strstr($this->options['db_fields'], '*')){
$sql_from = "*";
}
else{
$sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
}
$query = "SELECT ".$sql_from.
" FROM ".$this->options['table'].
" WHERE ".$this->options['usernamecol']." = " . $this->db->Quote($username);
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rset = $this->db->Execute( $query );
$res = $rset->fetchRow();
if (DB::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->getCode());
}
if (!is_array($res)) {
$this->activeUser = '';
return false;
}
if ($this->verifyPassword(trim($password, "\r\n"),
trim($res[$this->options['passwordcol']], "\r\n"),
$this->options['cryptType'])) {
// Store additional field values in the session
foreach ($res as $key => $value) {
if ($key == $this->options['passwordcol'] ||
$key == $this->options['usernamecol']) {
continue;
}
// Use reference to the auth object if exists
// This is because the auth session variable can change so a static call to setAuthData does not make sence
if(is_object($this->_auth_obj)){
$this->_auth_obj->setAuthData($key, $value);
} else {
Auth::setAuthData($key, $value);
}
}
return true;
}
$this->activeUser = $res[$this->options['usernamecol']];
return false;
}
// }}}
// {{{ listUsers()
function listUsers()
{
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
}
$retVal = array();
// Find if db_fileds contains a *, i so assume all col are selected
if(strstr($this->options['db_fields'], '*')){
$sql_from = "*";
}
else{
$sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
}
$query = sprintf("SELECT %s FROM %s",
$sql_from,
$this->options['table']
);
$res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC);
if (DB::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->getCode());
} else {
foreach ($res as $user) {
$user['username'] = $user[$this->options['usernamecol']];
$retVal[] = $user;
}
}
return $retVal;
}
// }}}
// {{{ addUser()
/**
* Add user to the storage container
*
* @access public
* @param string Username
* @param string Password
* @param mixed Additional information that are stored in the DB
*
* @return mixed True on success, otherwise error object
*/
function addUser($username, $password, $additional = "")
{
if (function_exists($this->options['cryptType'])) {
$cryptFunction = $this->options['cryptType'];
} else {
$cryptFunction = 'md5';
}
$additional_key = '';
$additional_value = '';
if (is_array($additional)) {
foreach ($additional as $key => $value) {
$additional_key .= ', ' . $key;
$additional_value .= ", '" . $value . "'";
}
}
$query = sprintf("INSERT INTO %s (%s, %s%s) VALUES ('%s', '%s'%s)",
$this->options['table'],
$this->options['usernamecol'],
$this->options['passwordcol'],
$additional_key,
$username,
$cryptFunction($password),
$additional_value
);
$res = $this->query($query);
if (DB::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->getCode());
} else {
return true;
}
}
// }}}
// {{{ removeUser()
/**
* Remove user from the storage container
*
* @access public
* @param string Username
*
* @return mixed True on success, otherwise error object
*/
function removeUser($username)
{
$query = sprintf("DELETE FROM %s WHERE %s = '%s'",
$this->options['table'],
$this->options['usernamecol'],
$username
);
$res = $this->query($query);
if (DB::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->getCode());
} else {
return true;
}
}
// }}}
}
function showDbg( $string ) {
print "
-- $string</P>";
}
function dump( $var, $str, $vardump = false ) {
print "<H4>$str</H4><pre>";
( !$vardump ) ? ( print_r( $var )) : ( var_dump( $var ));
print "</pre>";
}
?>

View File

@ -1,20 +0,0 @@
From: Rich Tango-Lowy (richtl#arscognita.com)
Date: Sat, May 29, 2004 11:20 am
OK, I hacked out an ADOdb container for PEAR-Auth. The error handling's
a bit of a mess, but all the methods work.
Copy ADOdb.php to your pear/Auth/Container/ directory.
Use the ADOdb container exactly as you would the DB
container, but specify 'ADOdb' instead of 'DB':
$dsn = "mysql://myuser:mypass@localhost/authdb";
$a = new Auth("ADOdb", $dsn, "loginFunction");
-------------------
John Lim adds:
See http://pear.php.net/manual/en/package.authentication.php

View File

@ -1,69 +0,0 @@
<html>
<head>
<title>ADODB Manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<XSTYLE
body,td {font-family:Arial,Helvetica,sans-serif;font-size:11pt}
pre {font-size:9pt}
.toplink {font-size:8pt}
/>
</head>
<body bgcolor="#FFFFFF">
<h3>ADOdb Library for PHP</h3>
<p>ADOdb is a suite of database libraries that allow you to connect to multiple
databases in a portable manner. Download from <a href=http://php.weblogs.com/adodb>http://php.weblogs.com/adodb</a>.
<ul><li>The ADOdb documentation has moved to <a href=docs-adodb.htm>docs-adodb.htm</a>
This allows you to query, update and insert records using a portable API.
<p><li>The ADOdb data dictionary docs are at <a href=docs-datadict.htm>docs-datadict.htm</a>.
This allows you to create database tables and indexes in a portable manner.
<p><li>The ADOdb database performance monitoring docs are at <a href=docs-perf.htm>docs-perf.htm</a>.
This allows you to perform health checks, tune and monitor your database.
<p><li>The ADOdb database-backed session docs are at <a href=docs-session.htm>docs-session.htm</a>.
</ul>
<p>
<h3>Installation</h3>
Make sure you are running PHP4.0.4 or later. Unpack all the files into a directory accessible by your webserver.
<p>
To test, try modifying some of the tutorial examples. Make sure you customize the connection settings correctly. You can debug using:
<pre>
&lt;?php
include('adodb/adodb.inc.php');
$db = <b>ADONewConnection</b>($driver); # eg. 'mysql' or 'oci8'
$db->debug = true;
$db-><b>Connect</b>($server, $user, $password, $database);
$rs = $db-><b>Execute</b>('select * from some_small_table');
print "&lt;pre>";
print_r($rs-><b>GetRows</b>());
print "&lt;/pre>";
?>
</pre>
<h3>How are people using ADOdb</h3>
Here are some examples of how people are using ADOdb (for a much longer list,
visit <a href="http://php.weblogs.com/adodb-cool-applications">http://php.weblogs.com/adodb-cool-applications</a>):
<ul>
<li> <strong>PhpLens</strong> is a commercial data grid component that allows
both cool Web designers and serious unshaved programmers to develop and
maintain databases on the Web easily. Developed by the author of ADOdb.
</li>
<li> <strong>PHAkt</strong>: PHP Extension for DreamWeaver Ultradev allows
you to script PHP in the popular Web page editor. Database handling provided
by ADOdb. </li>
<li> <strong>Analysis Console for Intrusion Databases (ACID)</strong>: PHP-based
analysis engine to search and process a database of security incidents
generated by security-related software such as IDSes and firewalls (e.g.
Snort, ipchains). By Roman Danyliw. </li>
<li> <strong>PostNuke</strong> is a very popular free content management system
and weblog system. It offers full CSS support, HTML 4.01 transitional
compliance throughout, an advanced blocks system, and is fully multi-lingual
enabled. </li>
<li><strong> EasyPublish CMS</strong> is another free content management system
for managing information and integrated modules on your internet, intranet-
and extranet-sites. From Norway. </li>
<li> <strong>NOLA</strong> is a full featured accounting, inventory, and job
tracking application. It is licensed under the GPL, and developed by Noguska.
</li>
</ul>
</body>
</html>

View File

@ -1,362 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Tips on Writing Portable SQL for Multiple Databases for PHP</title>
</head>
<body bgcolor=white>
<table width=100% border=0><tr><td><h2>Tips on Writing Portable SQL &nbsp;</h2></td><td>
<div align=right><img src="cute_icons_for_site/adodb.gif"></div></td></tr></table>
<p>Updated 18 Sep 2003. Added Portable Native SQL section.
<p>
If you are writing an application that is used in multiple environments and
operating systems, you need to plan to support multiple databases. This article
is based on my experiences with multiple database systems, stretching from 4th
Dimension in my Mac days, to the databases I currently use, which are: Oracle,
FoxPro, Access, MS SQL Server and MySQL. Although most of the advice here applies
to using SQL with Perl, Python and other programming languages, I will focus on PHP and how
the <a href="http://php.weblogs.com/adodb">ADOdb</a> database abstraction library
offers some solutions.<p></p>
<p>Most database vendors practice product lock-in. The best or fastest way to
do things is often implemented using proprietary extensions to SQL. This makes
it extremely hard to write portable SQL code that performs well under all conditions.
When the first ANSI committee got together in 1984 to standardize SQL, the database
vendors had such different implementations that they could only agree on the
core functionality of SQL. Many important application specific requirements
were not standardized, and after so many years since the ANSI effort began,
it looks as if much useful database functionality will never be standardized.
Even though ANSI-92 SQL has codified much more, we still have to implement portability
at the application level.</p>
<h3><b>Selects</b></h3>
<p>The SELECT statement has been standardized to a great degree. Nearly every
database supports the following:</p>
<p>SELECT [cols] FROM [tables]<br>
&nbsp;&nbsp;[WHERE conditions]<br>
&nbsp; [GROUP BY cols]<br>
&nbsp; [HAVING conditions] <br>
&nbsp; [ORDER BY cols]</p>
<p>But so many useful techniques can only be implemented by using proprietary
extensions. For example, when writing SQL to retrieve the first 10 rows for
paging, you could write...</p>
<table width="80%" border="1" cellspacing="0" cellpadding="0" align="center">
<tr>
<td><b>Database</b></td>
<td><b>SQL Syntax</b></td>
</tr>
<tr>
<td>DB2</td>
<td>select * from table fetch first 10 rows only</td>
</tr>
<tr>
<td>Informix</td>
<td>select first 10 * from table</td>
</tr>
<tr>
<td>Microsoft SQL Server and Access</td>
<td>select top 10 * from table</td>
</tr>
<tr>
<td>MySQL and PostgreSQL</td>
<td>select * from table limit 10</td>
</tr>
<tr>
<td>Oracle 8i</td>
<td>select * from (select * from table) where rownum &lt;= 10</td>
</tr>
</table>
<p>This feature of getting a subset of data is so useful that in the PHP class
library ADOdb, we have a SelectLimit( ) function that allows you to hide the
implementation details within a function that will rewrite your SQL for you:</p>
<pre>$connection-&gt;SelectLimit('select * from table', 10);
</pre>
<p><b>Selects: Fetch Modes</b></p>
<p>PHP allows you to retrieve database records as arrays. You can choose to have
the arrays indexed by field name or number. However different low-level PHP
database drivers are inconsistent in their indexing efforts. ADOdb allows you
to determine your prefered mode. You set this by setting the variable $ADODB_FETCH_MODE
to either of the constants ADODB_FETCH_NUM (for numeric indexes) or ADODB_FETCH_ASSOC
(using field names as an associative index).</p>
<p>The default behaviour of ADOdb varies depending on the database you are using.
For consistency, set the fetch mode to either ADODB_FETCH_NUM (for speed) or
ADODB_FETCH_ASSOC (for convenience) at the beginning of your code. </p>
<p><b>Selects: Counting Records</b></p>
<p>Another problem with SELECTs is that some databases do not return the number
of rows retrieved from a select statement. This is because the highest performance
databases will return records to you even before the last record has been found.
</p>
<p>In ADOdb, RecordCount( ) returns the number of rows returned, or will emulate
it by buffering the rows and returning the count after all rows have been returned.
This can be disabled for performance reasons when retrieving large recordsets
by setting the global variable $ADODB_COUNTRECS = false. This variable is checked
every time a query is executed, so you can selectively choose which recordsets
to count.</p>
<p>If you prefer to set $ADODB_COUNTRECS = false, ADOdb still has the PO_RecordCount(
) function. This will return the number of rows, or if it is not found, it will
return an estimate using SELECT COUNT(*):</p>
<pre>$rs = $db-&gt;Execute(&quot;select * from table where state=$state&quot;);
$numrows = $rs-&gt;PO_RecordCount('table', &quot;state=$state&quot;);</pre>
<p><b>Selects: Locking</b> </p>
<p>SELECT statements are commonly used to implement row-level locking of tables.
Other databases such as Oracle, Interbase, PostgreSQL and MySQL with InnoDB
do not require row-level locking because they use versioning to display data
consistent with a specific point in time.</p>
<p>Currently, I recommend encapsulating the row-level locking in a separate function,
such as RowLock($table, $where):</p>
<pre>$connection-&gt;BeginTrans( );
$connection-&gt;RowLock($table, $where); </pre>
<pre><font color=green># some operation</font></pre>
<pre>if ($ok) $connection-&gt;CommitTrans( );
else $connection-&gt;RollbackTrans( );
</pre>
<p><b>Selects: Outer Joins</b></p>
<p>Not all databases support outer joins. Furthermore the syntax for outer joins
differs dramatically between database vendors. One portable (and possibly slower)
method of implementing outer joins is using UNION.</p>
<p>For example, an ANSI-92 left outer join between two tables t1 and t2 could
look like:</p>
<pre>SELECT t1.col1, t1.col2, t2.cola <br> FROM t1 <i>LEFT JOIN</i> t2 ON t1.col = t2.col</pre>
<p>This can be emulated using:</p>
<pre>SELECT t1.col1, t1.col2, t2.cola FROM t1, t2 <br> WHERE t1.col = t2.col
UNION ALL
SELECT col1, col2, null FROM t1 <br> WHERE t1.col not in (select distinct col from t2)
</pre>
<p>Since ADOdb 2.13, we provide some hints in the connection object as to legal
join variations. This is still incomplete and sometimes depends on the database
version you are using, but is useful as a general guideline:</p>
<p><font face="Courier New, Courier, mono">$conn-&gt;leftOuter</font>: holds the
operator used for left outer joins (eg. '*='), or false if not known or not
available.<br>
<font face="Courier New, Courier, mono">$conn-&gt;rightOuter</font>: holds the
operator used for right outer joins (eg '=*'), or false if not known or not
available.<br>
<font face="Courier New, Courier, mono">$conn-&gt;ansiOuter</font>: boolean
that if true means that ANSI-92 style outer joins are supported, or false if
not known.</p>
<h3><b>Inserts</b> </h3>
<p>When you create records, you need to generate unique id's for each record.
There are two common techniques: (1) auto-incrementing columns and (2) sequences.
</p>
<p>Auto-incrementing columns are supported by MySQL, Sybase and Microsoft Access
and SQL Server. However most other databases do not support this feature. So
for portability, you have little choice but to use sequences. Sequences are
special functions that return a unique incrementing number every time you call
it, suitable to be used as database keys. In ADOdb, we use the GenID( ) function.
It has takes a parameter, the sequence name. Different tables can have different
sequences. </p>
<pre>$id = $connection-&gt;GenID('sequence_name');<br>$connection-&gt;Execute(&quot;insert into table (id, firstname, lastname) <br> values ($id, $firstname, $lastname)&quot;);</pre>
<p>For databases that do not support sequences natively, ADOdb emulates sequences
by creating a table for every sequence.</p>
<h3><b>Binding</b></h3>
<p>Binding variables in an SQL statement is another tricky feature. Binding is
useful because it allows pre-compilation of SQL. When inserting multiple records
into a database in a loop, binding can offer a 50% (or greater) speedup. However
many databases such as Access and MySQL do not support binding natively and
there is some overhead in emulating binding. Furthermore, different databases
(specificly Oracle!) implement binding differently. My recommendation is to
use binding if your database queries are too slow, but make sure you are using
a database that supports it like Oracle. </p>
<p>ADOdb supports portable Prepare/Execute with:</p>
<pre>$stmt = $db-&gt;Prepare('select * from customers where custid=? and state=?');
$rs = $db-&gt;Execute($stmt, array($id,'New York'));</pre>
<p>Oracle uses named bind placeholders, not "?", so to support portable binding, we have Param() that generates
the correct placeholder (available since ADOdb 3.92):
<pre><font color="#000000">$sql = <font color="#993300">'insert into table (col1,col2) values ('</font>.$DB-&gt;Param('a').<font color="#993300">','</font>.$DB-&gt;Param('b').<font color="#993300">')'</font>;
<font color="#006600"># generates 'insert into table (col1,col2) values (?,?)'
# or 'insert into table (col1,col2) values (:a,:b)</font>'
$stmt = $DB-&gt;Prepare($sql);
$stmt = $DB-&gt;Execute($stmt,array('one','two'));
</font></pre>
<a name="native"></a>
<h2>Portable Native SQL</h2>
<p>ADOdb provides the following functions for portably generating SQL functions
as strings to be merged into your SQL statements (some are only available since
ADOdb 3.92): </p>
<table width="75%" border="1" align=center>
<tr>
<td width=30%><b>Function</b></td>
<td><b>Description</b></td>
</tr>
<tr>
<td>DBDate($date)</td>
<td>Pass in a UNIX timestamp or ISO date and it will convert it to a date
string formatted for INSERT/UPDATE</td>
</tr>
<tr>
<td>DBTimeStamp($date)</td>
<td>Pass in a UNIX timestamp or ISO date and it will convert it to a timestamp
string formatted for INSERT/UPDATE</td>
</tr>
<tr>
<td>SQLDate($date, $fmt)</td>
<td>Portably generate a date formatted using $fmt mask, for use in SELECT
statements.</td>
</tr>
<tr>
<td>OffsetDate($date, $ndays)</td>
<td>Portably generate a $date offset by $ndays.</td>
</tr>
<tr>
<td>Concat($s1, $s2, ...)</td>
<td>Portably concatenate strings. Alternatively, for mssql use mssqlpo driver,
which allows || operator.</td>
</tr>
<tr>
<td>IfNull($fld, $replaceNull)</td>
<td>Returns a string that is the equivalent of MySQL IFNULL or Oracle NVL.</td>
</tr>
<tr>
<td>Param($name)</td>
<td>Generates bind placeholders, using ? or named conventions as appropriate.</td>
</tr>
<tr><td>$db->sysDate</td><td>Property that holds the SQL function that returns today's date</td>
</tr>
<tr><td>$db->sysTimeStamp</td><td>Property that holds the SQL function that returns the current
timestamp (date+time).
</td>
</tr>
<tr>
<td>$db->concat_operator</td><td>Property that holds the concatenation operator
</td>
</tr>
<tr><td>$db->length</td><td>Property that holds the name of the SQL strlen function.
</td></tr>
<tr><td>$db->upperCase</td><td>Property that holds the name of the SQL strtoupper function.
</td></tr>
<tr><td>$db->random</td><td>Property that holds the SQL to generate a random number between 0.00 and 1.00.
</td>
</tr>
<tr><td>$db->substr</td><td>Property that holds the name of the SQL substring function.
</td></tr>
</table>
<p>&nbsp; </p>
<h2>DDL and Tuning</h2>
There are database design tools such as ERWin or Dezign that allow you to generate data definition language commands such as ALTER TABLE or CREATE INDEX from Entity-Relationship diagrams.
<p>
However if you prefer to use a PHP-based table creation scheme, adodb provides you with this feature. Here is the code to generate the SQL to create a table with:
<ol>
<li> Auto-increment primary key 'ID', </li>
<li>The person's 'NAME' VARCHAR(32) NOT NULL and defaults to '', </li>
<li>The date and time of record creation 'CREATED', </li>
<li> The person's 'AGE', defaulting to 0, type NUMERIC(16). </li>
</ol>
<p>
Also create a compound index consisting of 'NAME' and 'AGE':
<pre>
$datadict = <strong>NewDataDictionary</strong>($connection);
$flds = "
<font color="#660000"> ID I AUTOINCREMENT PRIMARY,
NAME C(32) DEFAULT '' NOTNULL,
CREATED T DEFTIMESTAMP,
AGE N(16) DEFAULT 0</font>
";
$sql1 = $datadict-><strong>CreateTableSQL</strong>('tabname', $flds);
$sql2 = $datadict-><strong>CreateIndexSQL</strong>('idx_name_age', 'tabname', 'NAME,AGE');
</pre>
<h3>Data Types</h3>
<p>Stick to a few data types that are available in most databases. Char, varchar
and numeric/number are supported by most databases. Most other data types (including
integer, boolean and float) cannot be relied on being available. I recommend
using char(1) or number(1) to hold booleans. </p>
<p>Different databases have different ways of representing dates and timestamps/datetime.
ADOdb attempts to display all dates in ISO (YYYY-MM-DD) format. ADOdb also provides
DBDate( ) and DBTimeStamp( ) to convert dates to formats that are acceptable
to that database. Both functions accept Unix integer timestamps and date strings
in ISO format.</p>
<pre>$date1 = $connection-&gt;DBDate(time( ));<br>$date2 = $connection-&gt;DBTimeStamp('2002-02-23 13:03:33');</pre>
<p>We also provide functions to convert database dates to Unix timestamps:</p>
<pre>$unixts = $recordset-&gt;UnixDate('#2002-02-30#'); <font color="green"># MS Access date =&gt; unix timestamp</font></pre>
<p>The maximum length of a char/varchar field is also database specific. You can
only assume that field lengths of up to 250 characters are supported. This is
normally impractical for web based forum or content management systems. You
will need to be familiar with how databases handle large objects (LOBs). ADOdb
implements two functions, UpdateBlob( ) and UpdateClob( ) that allow you to
update fields holding Binary Large Objects (eg. pictures) and Character Large
Objects (eg. HTML articles):</p>
<pre><font color=green># for oracle </font>
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1,empty_blob())');
$conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');
<font color=green># non-oracle databases</font>
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');
</pre>
<p>Null handling is another area where differences can occur. This is a mine-field,
because 3-value logic is tricky.
<p>In general, I avoid using nulls except for dates and default all my numeric
and character fields to 0 or the empty string. This maintains consistency with
PHP, where empty strings and zero are treated as equivalent, and avoids SQL
ambiguities when you use the ANY and EXISTS operators. However if your database
has significant amounts of missing or unknown data, using nulls might be a good
idea.
<p>
ADOdb also supports a portable <a href=http://phplens.com/adodb/reference.functions.concat.html#ifnull>IfNull</a> function, so you can define what to display
if the field contains a null.
<h3><b>Stored Procedures</b></h3>
<p>Stored procedures are another problem area. Some databases allow recordsets
to be returned in a stored procedure (Microsoft SQL Server and Sybase), and
others only allow output parameters to be returned. Stored procedures sometimes
need to be wrapped in special syntax. For example, Oracle requires such code
to be wrapped in an anonymous block with BEGIN and END. Also internal sql operators
and functions such as +, ||, TRIM( ), SUBSTR( ) or INSTR( ) vary between vendors.
</p>
<p>An example of how to call a stored procedure with 2 parameters and 1 return
value follows:</p>
<pre> switch ($db->databaseType) {
case '<font color="#993300">mssql</font>':
$sql = <font color="#000000"><font color="#993333">'<font color="#993300">SP_RUNSOMETHING</font>'</font></font>; break;
case '<font color="#993300">oci8</font>':
$sql =
<font color="#993300"> </font><font color="#000000"><font color="#993300">&quot;declare RETVAL integer;begin :RETVAL := </font><font color="#000000"><font color="#993333"><font color="#993300">SP_RUNSOMETHING</font></font></font><font color="#993300">(:myid,:group);end;&quot;;
</font> break;</font>
default:
die('<font color="#993300">Unsupported feature</font>');
}
<font color="#000000"><font color="green"> # @RETVAL = SP_RUNSOMETHING @myid,@group</font>
$stmt = $db-&gt;PrepareSP($sql); <br> $db-&gt;Parameter($stmt,$id,'<font color="#993300">myid</font>');
$db-&gt;Parameter($stmt,$group,'<font color="#993300">group</font>');
<font color="green"># true indicates output parameter<br> </font>$db-&gt;Parameter($stmt,$ret,'<font color="#993300">RETVAL</font>',true);
$db-&gt;Execute($stmt); </font></pre>
<p>As you can see, the ADOdb API is the same for both databases. But the stored
procedure SQL syntax is quite different between databases and is not portable,
so be forewarned! However sometimes you have little choice as some systems only
allow data to be accessed via stored procedures. This is when the ultimate portability
solution might be the only solution: <i>treating portable SQL as a localization
exercise...</i></p>
<h3><b>SQL as a Localization Exercise</b></h3>
<p> In general to provide real portability, you will have to treat SQL coding
as a localization exercise. In PHP, it has become common to define separate
language files for English, Russian, Korean, etc. Similarly, I would suggest
you have separate Sybase, Intebase, MySQL, etc files, and conditionally include
the SQL based on the database. For example, each MySQL SQL statement would be
stored in a separate variable, in a file called 'mysql-lang.inc.php'.</p>
<pre>$sqlGetPassword = '<font color="#993300">select password from users where userid=%s</font>';
$sqlSearchKeyword = &quot;<font color="#993300">SELECT * FROM articles WHERE match (title,body) against (%s</font>)&quot;;</pre>
<p>In our main PHP file:</p>
<pre><font color=green># define which database to load...</font>
<b>$database = '<font color="#993300">mysql</font>';
include_once(&quot;<font color="#993300">$database-lang.inc.php</font>&quot;);</b>
$db = &amp;NewADOConnection($database);
$db->PConnect(...) or die('<font color="#993300">Failed to connect to database</font>');
<font color=green># search for a keyword $word</font>
$rs = $db-&gt;Execute(sprintf($sqlSearchKeyWord,$db-&gt;qstr($word)));</pre>
<p>Note that we quote the $word variable using the qstr( ) function. This is because
each database quotes strings using different conventions.</p>
<p>
<h3>Final Thoughts</h3>
<p>The best way to ensure that you have portable SQL is to have your data tables designed using
sound principles. Learn the theory of normalization and entity-relationship diagrams and model
your data carefully. Understand how joins and indexes work and how they are used to tune performance.
<p> Visit the following page for more references on database theory and vendors:
<a href="http://php.weblogs.com/sql_tutorial">http://php.weblogs.com/sql_tutorial</a>.
Also read this article on <a href=http://phplens.com/lens/php-book/optimizing-debugging-php.php>Optimizing PHP</a>.
<p>
<font size=1>(c) 2002-2003 John Lim.</font>
</body>
</html>

View File

@ -1,290 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Tutorial: Moving from MySQL to ADODB</title>
</head>
<body bgcolor=white>
<h1>Tutorial: Moving from MySQL to ADODB</h1>
<pre> You say eether and I say eyether,
You say neether and I say nyther;
Eether, eyether, neether, nyther -
Let's call the whole thing off !
<br>
You like potato and I like po-tah-to,
You like tomato and I like to-mah-to;
Potato, po-tah-to, tomato, to-mah-to -
Let's call the whole thing off !
</pre>
<p>I love this song, especially the version with Louis Armstrong and Ella singing
duet. It is all about how hard it is for two people in love to be compatible
with each other. It's about compromise and finding a common ground, and that's
what this article is all about.
<p>PHP is all about creating dynamic web-sites with the least fuss and the most
fun. To create these websites we need to use databases to retrieve login information,
to splash dynamic news onto the web page and store forum postings. So let's
say we were using the popular MySQL database for this. Your company has done
such a fantastic job that the Web site is more popular than your wildest dreams.
You find that MySQL cannot scale to handle the workload; time to switch databases.
<p> Unfortunately in PHP every database is accessed slightly differently. To connect
to MySQL, you would use <i>mysql_connect()</i>; when you decide to upgrade to
Oracle or Microsoft SQL Server, you would use <i>ocilogon() </i>or <i>mssql_connect()</i>
respectively. What is worse is that the parameters you use for the different
connect functions are different also.. One database says po-tato, the other
database says pota-to. Oh-oh.
<h3>Let's NOT call the whole thing off</h3>
<p>A database wrapper library such as ADODB comes in handy when you need to ensure portability. It provides
you with a common API to communicate with any supported database so you don't have to call things off. <p>
<p>ADODB stands for Active Data Objects DataBase (sorry computer guys are sometimes
not very original). ADODB currently supports MySQL, PostgreSQL, Oracle, Interbase,
Microsoft SQL Server, Access, FoxPro, Sybase, ODBC and ADO. You can download
ADODB from <a href=http://php.weblogs.com/adodb></a><a href="http://php.weblogs.com/adodb">http://php.weblogs.com/adodb</a>.
<h3>MySQL Example</h3>
<p>The most common database used with PHP is MySQL, so I guess you should be familiar
with the following code. It connects to a MySQL server at <i>localhost</i>,
database <i>mydb</i>, and executes an SQL select statement. The results are
printed, one line per row.
<pre><font color="#666600">$db = <b>mysql_connect</b>(&quot;localhost&quot;, &quot;root&quot;, &quot;password&quot;);
<b>mysql_select_db</b>(&quot;mydb&quot;,$db);</font>
<font color="#660000">$result = <b>mysql_query</b>(&quot;SELECT * FROM employees&quot;,$db)</font><code><font color="#663300">;
if ($result === false) die(&quot;failed&quot;);</font></code>
<font color="#006666"><b>while</b> ($fields =<b> mysql_fetch_row</b>($result)) &#123;
<b>for</b> ($i=0, $max=sizeof($fields); $i &lt; $max; $i++) &#123;
<b>print</b> $fields[$i].' ';
&#125;
<b>print</b> &quot;&lt;br&gt;\n&quot;;
&#125;</font>
</pre>
<p>The above code has been color-coded by section. The first section is the connection
phase. The second is the execution of the SQL, and the last section is displaying
the fields. The <i>while</i> loop scans the rows of the result, while the <i>for</i>
loop scans the fields in one row.</p>
<p>Here is the equivalent code in ADODB</p>
<pre><b><font color="#666600"> include(&quot;adodb.inc.php&quot;);</font></b><font color="#666600">
$db = <b>NewADOConnection</b>('mysql');
$db-&gt;<b>Connect</b>(&quot;localhost&quot;, &quot;root&quot;, &quot;password&quot;, &quot;mydb&quot;);</font>
<font color="#663300">$result = $db-&gt;<b>Execute</b>(&quot;SELECT * FROM employees&quot;);
</font><font color="#663300"></font><code><font color="#663300">if ($result === false) die(&quot;failed&quot;)</font></code><code><font color="#663300">;</font></code>
<font color="#006666"><b>while</b> (!$result-&gt;EOF) &#123;
<b>for</b> ($i=0, $max=$result-&gt;<b>FieldCount</b>(); $i &lt; $max; $i++)
<b>print</b> $result-&gt;fields[$i].' ';
$result-&gt;<b>MoveNext</b>();
<b>print</b> &quot;&lt;br&gt;\n&quot;;
&#125;</font> </pre>
<p></p>
<p>Now porting to Oracle is as simple as changing the second line to <code>NewADOConnection('oracle')</code>.
Let's walk through the code...</p>
<h3>Connecting to the Database</h3>
<p></p>
<pre><b><font color="#666600">include(&quot;adodb.inc.php&quot;);</font></b><font color="#666600">
$db = <b>NewADOConnection</b>('mysql');
$db-&gt;<b>Connect</b>(&quot;localhost&quot;, &quot;root&quot;, &quot;password&quot;, &quot;mydb&quot;);</font></pre>
<p>The connection code is a bit more sophisticated than MySQL's because our needs
are more sophisticated. In ADODB, we use an object-oriented approach to managing
the complexity of handling multiple databases. We have different classes to
handle different databases. If you aren't familiar with object-oriented programing,
don't worry -- the complexity is all hidden away in the<code> NewADOConnection()</code>
function.</p>
<p>To conserve memory, we only load the PHP code specific to the database you
are connecting to. We do this by calling <code>NewADOConnection(databasedriver)</code>.
Legal database drivers include <i>mysql, mssql, oracle, oci8, postgres, sybase,
vfp, access, ibase </i>and many others.</p>
<p>Then we create a new instance of the connection class by calling <code>NewADOConnection()</code>.
Finally we connect to the database using <code>$db-&gt;Connect(). </code></p>
<h3>Executing the SQL</h3>
<p><code><font color="#663300">$result = $db-&gt;<b>Execute</b>(&quot;SELECT *
FROM employees&quot;);<br>
if ($result === false) die(&quot;failed&quot;)</font></code><code><font color="#663300">;</font></code>
<br>
</p>
<p>Sending the SQL statement to the server is straight forward. Execute() will
return a recordset object on successful execution. You should check $result
as we do above.
<p>An issue that confuses beginners is the fact that we have two types of objects
in ADODB, the connection object and the recordset object. When do we use each?
<p>The connection object ($db) is responsible for connecting to the database,
formatting your SQL and querying the database server. The recordset object ($result)
is responsible for retrieving the results and formatting the reply as text or
as an array.
<p>The only thing I need to add is that ADODB provides several helper functions
for making INSERT and UPDATE statements easier, which we will cover in the Advanced
section.
<h3>Retrieving the Data<br>
</h3>
<pre><font color="#006666"><b>while</b> (!$result-&gt;EOF) &#123;
<b>for</b> ($i=0, $max=$result-&gt;<b>FieldCount</b>(); $i &lt; $max; $i++)
<b>print</b> $result-&gt;fields[$i].' ';
$result-&gt;<b>MoveNext</b>();
<b>print</b> &quot;&lt;br&gt;\n&quot;;
&#125;</font></pre>
<p>The paradigm for getting the data is that it's like reading a file. For every
line, we check first whether we have reached the end-of-file (EOF). While not
end-of-file, loop through each field in the row. Then move to the next line
(MoveNext) and repeat.
<p>The <code>$result-&gt;fields[]</code> array is generated by the PHP database
extension. Some database extensions do not index the array by field name.
To force indexing by name - that is associative arrays -
use the $ADODB_FETCH_MODE global variable.
<pre>
$<b>ADODB_FETCH_MODE</b> = ADODB_FETCH_NUM;
$rs1 = $db->Execute('select * from table');
$<b>ADODB_FETCH_MODE</b> = ADODB_FETCH_ASSOC;
$rs2 = $db->Execute('select * from table');
print_r($rs1->fields); // shows <i>array([0]=>'v0',[1] =>'v1')</i>
print_r($rs2->fields); // shows <i>array(['col1']=>'v0',['col2'] =>'v1')</i>
</pre>
<p>
As you can see in the above example, both recordsets store and use different fetch modes
based on the $ADODB_FETCH_MODE setting when the recordset was created by Execute().</p>
<h2>ADOConnection<a name="ADOConnection"></a></h2>
<p>Object that performs the connection to the database, executes SQL statements
and has a set of utility functions for standardising the format of SQL statements
for issues such as concatenation and date formats.</p>
<h3>Other Useful Functions</h3>
<p><code>$recordset-&gt;Move($pos)</code> scrolls to that particular row. ADODB supports forward
scrolling for all databases. Some databases will not support backwards scrolling.
This is normally not a problem as you can always cache records to simulate backwards
scrolling.
<p><code>$recordset-&gt;RecordCount()</code> returns the number of records accessed by the
SQL statement. Some databases will return -1 because it is not supported.
<p><code>$recordset-&gt;GetArray()</code> returns the result as an array.
<p><code>rs2html($recordset)</code> is a function that is generates a HTML table based on the
$recordset passed to it. An example with the relevant lines in bold:
<pre> include('adodb.inc.php');
<b>include('tohtml.inc.php');</b> /* includes the rs2html function */
$conn = &amp;ADONewConnection('mysql');
$conn-&gt;PConnect('localhost','userid','password','database');
$rs = $conn-&gt;Execute('select * from table');
<b> rs2html($rs)</b>; /* recordset to html table */ </pre>
<p>There are many other helper functions that are listed in the documentation available at <a href="http://php.weblogs.com/adodb_manual"></a><a href="http://php.weblogs.com/adodb_manual">http://php.weblogs.com/adodb_manual</a>.
<h2>Advanced Material</h2>
<h3>Inserts and Updates </h3>
<p>Let's say you want to insert the following data into a database.
<p><b>ID</b> = 3<br>
<b>TheDate</b>=mktime(0,0,0,8,31,2001) /* 31st August 2001 */<br>
<b>Note</b>= sugar why don't we call it off
<p>When you move to another database, your insert might no longer work.</p>
<p>The first problem is that each database has a different default date format.
MySQL expects YYYY-MM-DD format, while other databases have different defaults.
ADODB has a function called DBDate() that addresses this issue by converting
converting the date to the correct format.</p>
<p>The next problem is that the <b>don't</b> in the Note needs to be quoted. In
MySQL, we use <b>don\'t</b> but in some other databases (Sybase, Access, Microsoft
SQL Server) we use <b>don''t. </b>The qstr() function addresses this issue.</p>
<p>So how do we use the functions? Like this:</p>
<pre>$sql = &quot;INSERT INTO table (id, thedate,note) values (&quot;
. $<b>ID</b> . ','
. $db-&gt;DBDate($<b>TheDate</b>) .','
. $db-&gt;qstr($<b>Note</b>).&quot;)&quot;;
$db-&gt;Execute($sql);</pre>
<p>ADODB also supports <code>$connection-&gt;Affected_Rows()</code> (returns the
number of rows affected by last update or delete) and <code>$recordset-&gt;Insert_ID()</code>
(returns last autoincrement number generated by an insert statement). Be forewarned
that not all databases support the two functions.<br>
</p>
<h3>MetaTypes</h3>
<p>You can find out more information about each of the fields (I use the words
fields and columns interchangebly) you are selecting by calling the recordset
method <code>FetchField($fieldoffset)</code>. This will return an object with
3 properties: name, type and max_length.
<pre>For example:</pre>
<pre>$recordset = $conn-&gt;Execute(&quot;select adate from table&quot;);<br>$f0 = $recordset-&gt;FetchField(0);
</pre>
<p>Then <code>$f0-&gt;name</code> will hold <i>'adata'</i>, <code>$f0-&gt;type</code>
will be set to '<i>date'</i>. If the max_length is unknown, it will be set to
-1.
<p>One problem with handling different databases is that each database often calls
the same type by a different name. For example a <i>timestamp</i> type is called
<i>datetime</i> in one database and <i>time</i> in another. So ADODB has a special
<code>MetaType($type, $max_length)</code> function that standardises the types
to the following:
<p>C: character and varchar types<br>
X: text or long character (eg. more than 255 bytes wide).<br>
B: blob or binary image<br>
D: date<br>
T: timestamp<br>
L: logical (boolean)<br>
I: integer<br>
N: numeric (float, double, money)
<p>In the above date example,
<p><code>$recordset = $conn-&gt;Execute(&quot;select adate from table&quot;);<br>
$f0 = $recordset-&gt;FetchField(0);<br>
$type = $recordset-&gt;MetaType($f0-&gt;type, $f0-&gt;max_length);<br>
print $type; /* should print 'D'</code> */
<p>
<p><b>Select Limit and Top Support</b>
<p>ADODB has a function called $connection->SelectLimit($sql,$nrows,$offset) that allows
you to retrieve a subset of the recordset. This will take advantage of native
SELECT TOP on Microsoft products and SELECT ... LIMIT with PostgreSQL and MySQL, and
emulated if the database does not support it.
<p><b>Caching Support</b>
<p>ADODB allows you to cache recordsets in your file system, and only requery the database
server after a certain timeout period with $connection->CacheExecute($secs2cache,$sql) and
$connection->CacheSelectLimit($secs2cache,$sql,$nrows,$offset).
<p><b>PHP4 Session Handler Support</b>
<p>ADODB also supports PHP4 session handlers. You can store your session variables
in a database for true scalability using ADODB. For further information, visit
<a href="http://php.weblogs.com/adodb-sessions"></a><a href="http://php.weblogs.com/adodb-sessions">http://php.weblogs.com/adodb-sessions</a>
<h3>Commercial Use Encouraged</h3>
<p>If you plan to write commercial PHP applications that you want to resell, you should consider ADODB. It has been released using the lesser GPL, which means you can legally include it in commercial applications, while keeping your code proprietary. Commercial use of ADODB is strongly encouraged! We are using it internally for this reason.<p>
<h2>Conclusion</h2>
<p>As a thank you for finishing this article, here are the complete lyrics for
<i>let's call the whole thing off</i>.<br>
<br>
<pre>
Refrain
<br>
You say eether and I say eyether,
You say neether and I say nyther;
Eether, eyether, neether, nyther -
Let's call the whole thing off !
<br>
You like potato and I like po-tah-to,
You like tomato and I like to-mah-to;
Potato, po-tah-to, tomato, to-mah-to -
Let's call the whole thing off !
<br>
But oh, if we call the whole thing off, then we must part.
And oh, if we ever part, then that might break my heart.
<br>
So, if you like pajamas and I like pa-jah-mas,
I'll wear pajamas and give up pa-jah-mas.
For we know we
Need each other, so we
Better call the calling off off.
Let's call the whole thing off !
<br>
Second Refrain
<br>
You say laughter and I say lawfter,
You say after and I say awfter;
Laughter, lawfter, after, awfter -
Let's call the whole thing off !
<br>
You like vanilla and I like vanella,
You, sa's'parilla and I sa's'parella;
Vanilla, vanella, choc'late, strawb'ry -
Let's call the whole thing off !
<br>
But oh, if we call the whole thing off, then we must part.
And oh, if we ever part, then that might break my heart.
<br>
So, if you go for oysters and I go for ersters,
I'll order oysters and cancel the ersters.
For we know we
Need each other, so we
Better call the calling off off.
Let's call the whole thing off !
</pre>
<p><font size=2>Song and lyrics by George and Ira Gershwin, introduced by Fred Astaire and Ginger Rogers
in the film "Shall We Dance?" </font><p>
<p>
(c)2001-2002 John Lim.
</body>
</html>

View File

@ -157,10 +157,11 @@ function search_users($courseid, $groupid, $searchtext, $sort='', $exceptions=''
} else {
if ($groupid) {
//TODO:check. Remove group DB dependencies.
return get_records_sql("SELECT u.id, u.firstname, u.lastname, u.email
FROM {$CFG->prefix}user u,
{$CFG->prefix}groups_members g
WHERE $select AND g.groupid = '$groupid' AND g.userid = u.id
".groups_members_from_sql()."
WHERE $select AND ".groups_members_where_sql($groupid, 'u.id')."
AND ($fullname $LIKE '%$searchtext%' OR u.email $LIKE '%$searchtext%')
$except $order");
} else {
@ -375,7 +376,11 @@ function get_users_not_fully_set_up($cutofftime=2000000000) {
}
/**
/** TODO: functions now in /group/lib/legacylib.php (3)
get_groups
get_group_users
user_group
* Returns an array of group objects that the user is a member of
* in the given course. If userid isn't specified, then return a
* list of all groups in the course.
@ -384,7 +389,7 @@ function get_users_not_fully_set_up($cutofftime=2000000000) {
* @param int $courseid The id of the course in question.
* @param int $userid The id of the user in question as found in the 'user' table 'id' field.
* @return object
*/
*
function get_groups($courseid, $userid=0) {
global $CFG;
@ -410,7 +415,7 @@ function get_groups($courseid, $userid=0) {
* @param string $sort ?
* @param string $exceptions ?
* @return object
*/
*
function get_group_users($groupid, $sort='u.lastaccess DESC', $exceptions='', $fields='u.*') {
global $CFG;
if (!empty($exceptions)) {
@ -441,7 +446,7 @@ function get_group_users($groupid, $sort='u.lastaccess DESC', $exceptions='', $f
* @param int $userid The id of the user as found in the 'user' table.
* @param int $groupid The id of the group the user is in.
* @return object
*/
*
function user_group($courseid, $userid) {
global $CFG;
@ -453,7 +458,7 @@ function user_group($courseid, $userid) {
AND m.userid = '$userid'
ORDER BY name ASC");
}
*/

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="lib/db" VERSION="20061122" COMMENT="XMLDB file for core Moodle tables"
<XMLDB PATH="lib/db" VERSION="20061204" COMMENT="XMLDB file for core Moodle tables"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
>
@ -324,7 +324,7 @@
<INDEX NAME="courseid" UNIQUE="false" FIELDS="courseid"/>
</INDEXES>
</TABLE>
<TABLE NAME="grade_preferences" COMMENT="Preferences of the gradebook for each course" PREVIOUS="grade_letter" NEXT="groups">
<TABLE NAME="grade_preferences" COMMENT="Preferences of the gradebook for each course" PREVIOUS="grade_letter" NEXT="log">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="courseid"/>
<FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="preference"/>
@ -338,43 +338,7 @@
<INDEX NAME="courseid-preference" UNIQUE="true" FIELDS="courseid, preference"/>
</INDEXES>
</TABLE>
<TABLE NAME="groups" COMMENT="Each record is a group in a course" PREVIOUS="grade_preferences" NEXT="groups_members">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="courseid"/>
<FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="254" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="courseid" NEXT="description"/>
<FIELD NAME="description" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="password"/>
<FIELD NAME="password" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="description" NEXT="lang"/>
<FIELD NAME="lang" TYPE="char" LENGTH="10" NOTNULL="true" DEFAULT="en" SEQUENCE="false" ENUM="false" PREVIOUS="password" NEXT="theme"/>
<FIELD NAME="theme" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="lang" NEXT="picture"/>
<FIELD NAME="picture" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="theme" NEXT="hidepicture"/>
<FIELD NAME="hidepicture" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="picture" NEXT="timecreated"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="hidepicture" NEXT="timemodified"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="timecreated"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups"/>
</KEYS>
<INDEXES>
<INDEX NAME="courseid" UNIQUE="false" FIELDS="courseid"/>
</INDEXES>
</TABLE>
<TABLE NAME="groups_members" COMMENT="Lists memberships of users to groups" PREVIOUS="groups" NEXT="log">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="groupid"/>
<FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="userid"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupid" NEXT="timeadded"/>
<FIELD NAME="timeadded" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="userid"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_members"/>
</KEYS>
<INDEXES>
<INDEX NAME="groupid" UNIQUE="false" FIELDS="groupid" NEXT="userid"/>
<INDEX NAME="userid" UNIQUE="false" FIELDS="userid" PREVIOUS="groupid"/>
</INDEXES>
</TABLE>
<TABLE NAME="log" COMMENT="Every action is logged as far as possible" PREVIOUS="groups_members" NEXT="log_display">
<TABLE NAME="log" COMMENT="Every action is logged as far as possible" PREVIOUS="grade_preferences" NEXT="log_display">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="time"/>
<FIELD NAME="time" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="userid"/>

File diff suppressed because it is too large Load Diff

View File

@ -1,563 +0,0 @@
<DBMIGRATION type="lib" VERSION="2005120100">
<TABLES>
<TABLE name="adodb_logsql">
<FIELDS>
<FIELD name="sql0" method="NO_CONV" type="varchar" length="250" />
<FIELD name="sql1" method="NO_CONV" type="text" length="0" />
<FIELD name="params" method="NO_CONV" type="text" length="0" />
<FIELD name="tracer" method="NO_CONV" type="text" length="0" />
</FIELDS>
</TABLE>
<TABLE name="user_lastaccess" />
<TABLE name="user_info_category">
<FIELDS>
<FIELD name="name" method="PHP_FUNCTION" type="varchar" length="255">
<PHP_FUNCTION>
migrate2utf8_user_info_category_name(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="user_info_data">
<FIELDS>
<FIELD name="data" method="PHP_FUNCTION" type="longtext" length="0">
<PHP_FUNCTION>
migrate2utf8_user_info_data_data(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="user_info_field">
<FIELDS>
<FIELD name="name" method="PHP_FUNCTION" type="varchar" length="255">
<PHP_FUNCTION>
migrate2utf8_user_info_field_name(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="datatype" method="NO_CONV" type="varchar" length="255" />
<FIELD name="defaultdata" method="PHP_FUNCTION" type="longtext" length="0">
<PHP_FUNCTION>
migrate2utf8_user_info_field_defaultdata(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="role">
<FIELDS>
<FIELD name="name" method="PHP_FUNCTION" type="varchar" length="255">
<PHP_FUNCTION>
migrate2utf8_role_name(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="shortname" method="NO_CONV" type="varchar" length="100">
<PHP_FUNCTION>
migrate2utf8_role_shortname(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="description" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_role_description(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="context" />
<TABLE name="role_allow_assign" />
<TABLE name="role_allow_override" />
<TABLE name="role_assignments">
<FIELDS>
<FIELD name="enrol" method="NO_CONV" type="varchar" length="20" />
</FIELDS>
</TABLE>
<TABLE name="role_capabilities">
<FIELDS>
<FIELD name="capability" method="NO_CONV" type="varchar" length="255" dropindex="roleid-contextid-capability" adduniqueindex ="roleid-contextid-capability(roleid, contextid, capability(255))" />
</FIELDS>
</TABLE>
<TABLE name="capabilities">
<FIELDS>
<FIELD name="name" method="NO_CONV" type="varchar" length="255" dropindex="name" adduniqueindex ="name(name(255))" />
<FIELD name="captype" method="NO_CONV" type="varchar" length="50" />
<FIELD name="component" method="NO_CONV" type="varchar" length="100" />
</FIELDS>
</TABLE>
<TABLE name="role_names">
<FIELDS>
<FIELD name="text" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_role_names_text(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="blog_tag_instance" />
<TABLE name="post">
<FIELDS>
<FIELD name="module" method="NO_CONV" type="varchar" length="20" dropindex="post_module_idx" addindex="post_module_idx(module(20))"/>
<FIELD name="subject" method="PHP_FUNCTION" type="varchar" length="128" dropindex="post_subject_idx" addindex=" post_subject_idx(subject(128))">
<PHP_FUNCTION>
migrate2utf8_post_subject(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="summary" method="PHP_FUNCTION" type="longtext" length="0">
<PHP_FUNCTION>
migrate2utf8_post_summary(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="content" method="PHP_FUNCTION" type="longtext" length="0">
<PHP_FUNCTION>
migrate2utf8_post_content(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="uniquehash" method="NO_CONV" type="varchar" length="128" />
<FIELD name="publishstate" method="NO_CONV" type="enum('draft', 'site', 'public')" length="0" default="draft" />
</FIELDS>
</TABLE>
<TABLE name="tags">
<FIELDS>
<FIELD name="type" method="NO_CONV" type="varchar" length="20" dropindex="tags_typeuserid_idx" addindex="tags_typeuserid_idx(type(20), userid)" />
<FIELD name="text" method="PHP_FUNCTION" type="varchar" length="255" dropindex="tags_text_idx" addindex="tags_text_idx(text(255))">
<PHP_FUNCTION>
migrate2utf8_tags_text(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="config">
<FIELDS>
<FIELD name="name" method="NO_CONV" type="varchar" length="255" dropindex="name" adduniqueindex="name (name(255))"/>
<FIELD name="value" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_config_value(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="config_plugins">
<FIELDS>
<FIELD name="plugin" method="NO_CONV" type="varchar" length="100" dropindex="plugin_name" default="core"/>
<FIELD name="name" method="NO_CONV" type="varchar" length="100" adduniqueindex="plugin_name(plugin(100), name(100))"/>
<FIELD name="value" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_config_plugins_value(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="course_allowed_modules" />
<TABLE name="course_display" />
<TABLE name="course_meta" />
<TABLE name="course_modules" />
<TABLE name="course_categories">
<FIELDS>
<FIELD name="name" method="PHP_FUNCTION" type="varchar" length="255">
<PHP_FUNCTION>
migrate2utf8_course_categories_name(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="description" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_course_categories_description(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="path" method="NO_CONV" type="varchar" length="255" />
</FIELDS>
</TABLE>
<TABLE name="course_sections">
<FIELDS>
<FIELD name="summary" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_course_sections_summary(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="sequence" method="NO_CONV" type="text" length="0" />
</FIELDS>
</TABLE>
<TABLE name="course_request">
<FIELDS>
<FIELD name="fullname" method="PHP_FUNCTION" type="varchar" length="254">
<PHP_FUNCTION>
migrate2utf8_course_request_fullname(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="shortname" method="PHP_FUNCTION" type="varchar" length="15" dropindex="shortname" addindex="shortname(shortname(15))">
<PHP_FUNCTION>
migrate2utf8_course_request_shortname(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="summary" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_course_request_summary(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="reason" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_course_request_reason(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="password" method="PHP_FUNCTION" type="varchar" length="50">
<PHP_FUNCTION>
migrate2utf8_course_request_password(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="event">
<FIELDS>
<FIELD name="name" method="PHP_FUNCTION" type="varchar" length="255">
<PHP_FUNCTION>
migrate2utf8_event_name(RECORDID);
</PHP_FUNCTION>
</FIELD>
<FIELD name="description" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_event_description(RECORDID);
</PHP_FUNCTION>
</FIELD>
<FIELD name="modulename" method="NO_CONV" type="varchar" length="20" />
<FIELD name="eventtype" method="NO_CONV" type="varchar" length="20" />
<FIELD name="uuid" method="NO_CONV" type="varchar" length="36" />
</FIELDS>
</TABLE>
<TABLE name="cache_filters">
<FIELDS>
<FIELD name="md5key" method="NO_CONV" type="varchar" length="32" dropindex="filtermd5key"/>
<FIELD name="filter" method="NO_CONV" type="varchar" length="32" addindex="filtermd5key(filter(32),md5key(32))"/>
<FIELD name="rawtext" method="NO_CONV" type="text" length="0" />
</FIELDS>
</TABLE>
<TABLE name="cache_text">
<FIELDS>
<FIELD name="md5key" method="NO_CONV" type="varchar" length="32" dropindex="md5key" addindex="md5key(md5key(32))"/>
<FIELD name="formattedtext" method="NO_CONV" type="longtext" length="0" />
</FIELDS>
</TABLE>
<TABLE name="grade_item" />
<TABLE name="grade_preferences" />
<TABLE name="grade_category">
<FIELDS>
<FIELD name="name" method="PHP_FUNCTION" type="varchar" length="64">
<PHP_FUNCTION>
migrate2utf8_grade_category_name(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="grade_exceptions" />
<TABLE name="grade_letter">
<FIELDS>
<FIELD name="letter" method="PHP_FUNCTION" type="varchar" length="8" default="NA">
<PHP_FUNCTION>
migrate2utf8_grade_letter_letter(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="groups_members" />
<TABLE name="groups">
<FIELDS>
<FIELD name="name" method="PHP_FUNCTION" type="varchar" length="254">
<PHP_FUNCTION>
migrate2utf8_groups_name(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="description" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_groups_description(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="password" method="PHP_FUNCTION" type="varchar" length="50">
<PHP_FUNCTION>
migrate2utf8_groups_password(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="theme" method="NO_CONV" type="varchar" length="50" />
<FIELD name="lang" method="PHP_FUNCTION" type="varchar" length="10" default="en">
<PHP_FUNCTION>
migrate2utf8_groups_lang(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="log">
<FIELDS>
<FIELD name="ip" method="NO_CONV" type="varchar" length="15" dropindex="timecoursemoduleaction"/>
<FIELD name="module" method="NO_CONV" type="varchar" length="20" dropindex="coursemoduleaction"/>
<FIELD name="action" method="NO_CONV" type="varchar" length="15" addindex="timecoursemoduleaction(time, course, module(20), action(15))" />
<FIELD name="url" method="NO_CONV" type="varchar" length="100" addindex="coursemoduleaction(course, module(20), action(15))" />
<FIELD name="info" method="NO_CONV" type="varchar" length="255" dropindex="info" addindex="info(info(255))" />
</FIELDS>
</TABLE>
<TABLE name="log_display">
<FIELDS>
<FIELD name="mtable" method="NO_CONV" type="varchar" length="30" dropindex="moduleaction"/>
<FIELD name="field" method="NO_CONV" type="varchar" length="50" />
<FIELD name="module" method="NO_CONV" type="varchar" length="30" />
<FIELD name="action" method="NO_CONV" type="varchar" length="40" addindex="moduleaction(module(30), action(40))"/>
</FIELDS>
</TABLE>
<TABLE name="message_contacts" />
<TABLE name="message">
<FIELDS>
<FIELD name="message" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_message_message(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="messagetype" method="NO_CONV" type="varchar" length="50" />
</FIELDS>
</TABLE>
<TABLE name="message_read">
<FIELDS>
<FIELD name="message" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_message_read_message(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="messagetype" method="NO_CONV" type="varchar" length="50" />
</FIELDS>
</TABLE>
<TABLE name="modules">
<FIELDS>
<FIELD name="name" method="NO_CONV" type="varchar" length="20" dropindex="name" addindex="name(name(20))"/>
<FIELD name="search" method="PHP_FUNCTION" type="varchar" length="255">
<PHP_FUNCTION>
migrate2utf8_modules_search(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="scale">
<FIELDS>
<FIELD name="name" method="PLAIN_SQL_UPDATE" type="varchar" length="255">
<SQL_DETECT_USER>
SELECT s.userid
FROM {$CFG->prefix}scale s
WHERE s.id = RECORDID
</SQL_DETECT_USER>
<SQL_DETECT_COURSE>
SELECT s.courseid as course
FROM {$CFG->prefix}scale s
WHERE s.id = RECORDID
</SQL_DETECT_COURSE>
</FIELD>
<FIELD name="scale" method="PLAIN_SQL_UPDATE" type="text" length="0">
<SQL_DETECT_USER>
SELECT s.userid
FROM {$CFG->prefix}scale s
WHERE s.id = RECORDID
</SQL_DETECT_USER>
<SQL_DETECT_COURSE>
SELECT s.courseid as course
FROM {$CFG->prefix}scale s
WHERE s.id = RECORDID
</SQL_DETECT_COURSE>
</FIELD>
<FIELD name="description" method="PLAIN_SQL_UPDATE" type="text" length="0">
<SQL_DETECT_USER>
SELECT s.userid
FROM {$CFG->prefix}scale s
WHERE s.id = RECORDID
</SQL_DETECT_USER>
<SQL_DETECT_COURSE>
SELECT s.courseid as course
FROM {$CFG->prefix}scale s
WHERE s.id = RECORDID
</SQL_DETECT_COURSE>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="sessions2">
<FIELDS>
<FIELD name="sesskey" method="NO_CONV" type="varchar" length="64" dropprimary="true" addprimary="(sesskey(64))"/>
<FIELD name="expireref" method="NO_CONV" type="varchar" length="250" />
<FIELD name="sessdata" method="NO_CONV" type="longtext" length="0" />
</FIELDS>
</TABLE>
<TABLE name="timezone">
<FIELDS>
<FIELD name="name" method="NO_CONV" type="varchar" length="100" />
<FIELD name="tzrule" method="NO_CONV" type="varchar" length="20" />
<FIELD name="dst_time" method="NO_CONV" type="varchar" length="5" />
<FIELD name="std_time" method="NO_CONV" type="varchar" length="5" />
</FIELDS>
</TABLE>
<TABLE name="stats_daily">
<FIELDS>
<FIELD name="stattype" method="NO_CONV" type="enum('enrolments', 'activity', 'logins')" default="activity" length="0" />
</FIELDS>
</TABLE>
<TABLE name="stats_weekly">
<FIELDS>
<FIELD name="stattype" method="NO_CONV" type="enum('enrolments', 'activity', 'logins')" default="activity" length="0" />
</FIELDS>
</TABLE>
<TABLE name="stats_monthly">
<FIELDS>
<FIELD name="stattype" method="NO_CONV" type="enum('enrolments', 'activity', 'logins')" default="activity" length="0" />
</FIELDS>
</TABLE>
<TABLE name="stats_user_daily">
<FIELDS>
<FIELD name="stattype" method="NO_CONV" type="varchar" length="30" />
</FIELDS>
</TABLE>
<TABLE name="stats_user_monthly">
<FIELDS>
<FIELD name="stattype" method="NO_CONV" type="varchar" length="30" />
</FIELDS>
</TABLE>
<TABLE name="stats_user_weekly">
<FIELDS>
<FIELD name="stattype" method="NO_CONV" type="varchar" length="30" />
</FIELDS>
</TABLE>
<TABLE name="user_preferences">
<FIELDS>
<FIELD name="name" method="NO_CONV" type="varchar" length="50" dropindex="useridname" addindex="useridname(userid, name(50))"/>
<FIELD name="value" method="NO_CONV" type="varchar" length="255" />
</FIELDS>
</TABLE>
<TABLE name="course">
<FIELDS>
<FIELD name="currency" method="NO_CONV" type="char" length="3" />
<FIELD name="enrol" method="NO_CONV" type="varchar" length="20" />
<FIELD name="password" method="PHP_FUNCTION" type="varchar" length="50">
<PHP_FUNCTION>
migrate2utf8_course_password(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="fullname" method="PHP_FUNCTION" type="varchar" length="254">
<PHP_FUNCTION>
migrate2utf8_course_fullname(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="shortname" method="PHP_FUNCTION" type="varchar" length="100" dropindex="shortname" addindex="shortname(shortname(100))">
<PHP_FUNCTION>
migrate2utf8_course_shortname(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="idnumber" method="PHP_FUNCTION" type="varchar" length="100" dropindex="idnumber" addindex="idnumber(idnumber(100))">
<PHP_FUNCTION>
migrate2utf8_course_idnumber(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="summary" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_course_summary(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="format" method="NO_CONV" type="varchar" length="10" default="topics"/>
<FIELD name="modinfo" method="PHP_FUNCTION" type="longtext" length="0">
<PHP_FUNCTION>
migrate2utf8_course_modinfo(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="teacher" method="PHP_FUNCTION" type="varchar" length="100" default="Teacher">
<PHP_FUNCTION>
migrate2utf8_course_teacher(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="teachers" method="PHP_FUNCTION" type="varchar" length="100" default="Teachers">
<PHP_FUNCTION>
migrate2utf8_course_teachers(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="student" method="PHP_FUNCTION" type="varchar" length="100" default="Student">
<PHP_FUNCTION>
migrate2utf8_course_student(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="students" method="PHP_FUNCTION" type="varchar" length="100" default="Students">
<PHP_FUNCTION>
migrate2utf8_course_students(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="cost" method="PHP_FUNCTION" type="varchar" length="10">
<PHP_FUNCTION>
migrate2utf8_course_cost(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="theme" method="NO_CONV" type="varchar" length="50" />
<FIELD name="lang" method="PHP_FUNCTION" type="varchar" length="10" default="en_utf8">
<PHP_FUNCTION>
migrate2utf8_course_lang(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
<TABLE name="user">
<FIELDS>
<FIELD name="auth" method="NO_CONV" type="varchar" length="20" dropindex="auth" addindex="auth(auth(20))" default="manual"/>
<FIELD name="username" method="NO_CONV" type="varchar" length="100" dropindex="username" adduniqueindex="username(username(100))"/>
<FIELD name="password" method="NO_CONV" type="varchar" length="32" />
<FIELD name="idnumber" method="PHP_FUNCTION" type="varchar" length="64" dropindex="idnumber" addindex="idnumber(idnumber(64))">
<PHP_FUNCTION>
migrate2utf8_user_idnumber(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="firstname" method="PHP_FUNCTION" type="varchar" length="100" dropindex="user_firstname" addindex="user_firstname(firstname(100))">
<PHP_FUNCTION>
migrate2utf8_user_firstname(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="lastname" method="PHP_FUNCTION" type="varchar" length="100" dropindex="user_lastname" addindex="user_lastname(lastname(100))">
<PHP_FUNCTION>
migrate2utf8_user_lastname(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="email" method="NO_CONV" type="varchar" length="100" dropindex="user_email" addindex="user_email(email(100))"/>
<FIELD name="icq" method="NO_CONV" type="varchar" length="15" />
<FIELD name="skype" method="NO_CONV" type="varchar" length="50" />
<FIELD name="yahoo" method="NO_CONV" type="varchar" length="50" />
<FIELD name="aim" method="NO_CONV" type="varchar" length="50" />
<FIELD name="msn" method="NO_CONV" type="varchar" length="50" />
<FIELD name="phone1" method="NO_CONV" type="varchar" length="20" />
<FIELD name="phone2" method="NO_CONV" type="varchar" length="20" />
<FIELD name="institution" method="PHP_FUNCTION" type="varchar" length="40">
<PHP_FUNCTION>
migrate2utf8_user_institution(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="department" method="PHP_FUNCTION" type="varchar" length="30">
<PHP_FUNCTION>
migrate2utf8_user_department(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="address" method="PHP_FUNCTION" type="varchar" length="70">
<PHP_FUNCTION>
migrate2utf8_user_address(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="city" method="PHP_FUNCTION" type="varchar" length="20" dropindex="user_city" addindex="user_city(city(20))">
<PHP_FUNCTION>
migrate2utf8_user_city(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="country" method="NO_CONV" type="char" length="2" dropindex="user_country" addindex="user_country(country(2))"/>
<FIELD name="theme" method="NO_CONV" type="varchar" length="50" />
<FIELD name="timezone" method="NO_CONV" type="varchar" length="100" />
<FIELD name="lastip" method="NO_CONV" type="varchar" length="15" />
<FIELD name="secret" method="PHP_FUNCTION" type="varchar" length="15">
<PHP_FUNCTION>
migrate2utf8_user_secret(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="url" method="NO_CONV" type="varchar" length="255" />
<FIELD name="description" method="PHP_FUNCTION" type="text" length="0">
<PHP_FUNCTION>
migrate2utf8_user_description(RECORDID)
</PHP_FUNCTION>
</FIELD>
<FIELD name="lang" method="PHP_FUNCTION" type="varchar" length="10">
<PHP_FUNCTION>
migrate2utf8_user_lang(RECORDID)
</PHP_FUNCTION>
</FIELD>
</FIELDS>
</TABLE>
</TABLES>
</DBMIGRATION>

View File

@ -365,45 +365,6 @@ CREATE TABLE `prefix_grade_preferences` (
# --------------------------------------------------------
#
# Table structure for table `group`
#
CREATE TABLE `prefix_groups` (
`id` int(10) unsigned NOT NULL auto_increment,
`courseid` int(10) unsigned NOT NULL default '0',
`name` varchar(254) NOT NULL default '',
`description` text NOT NULL default '',
`password` varchar(50) NOT NULL default '',
`lang` varchar(10) NOT NULL default 'en',
`theme` varchar(50) NOT NULL default '',
`picture` int(10) unsigned NOT NULL default '0',
`hidepicture` int(2) unsigned NOT NULL default '0',
`timecreated` int(10) unsigned NOT NULL default '0',
`timemodified` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `courseid` (`courseid`)
) TYPE=MyISAM COMMENT='Each record is a group in a course.';
# --------------------------------------------------------
#
# Table structure for table `group_members`
#
CREATE TABLE `prefix_groups_members` (
`id` int(10) unsigned NOT NULL auto_increment,
`groupid` int(10) unsigned NOT NULL default '0',
`userid` int(10) unsigned NOT NULL default '0',
`timeadded` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `groupid` (`groupid`),
KEY `userid` (`userid`)
) TYPE=MyISAM COMMENT='Lists memberships of users to groups';
# --------------------------------------------------------
#
# Table structure for table `log`
#

Some files were not shown because too many files have changed in this diff Show More