diff --git a/admin/repository.php b/admin/repository.php index 2a1e803757ee2..113e3ae8e3235 100644 --- a/admin/repository.php +++ b/admin/repository.php @@ -1,16 +1,18 @@ -dirroot . '/repository/lib.php'); require_once($CFG->libdir . '/adminlib.php'); $CFG->pagepath = 'admin/managerepositories'; -// id of repository -$edit = optional_param('edit', 0, PARAM_INT); +$edit = optional_param('edit', 0, PARAM_ALPHA); $new = optional_param('new', '', PARAM_FORMAT); -$hide = optional_param('hide', 0, PARAM_INT); -$delete = optional_param('delete', 0, PARAM_INT); +$hide = optional_param('hide', 0, PARAM_ALPHA); +$delete = optional_param('delete', 0, PARAM_ALPHA); $sure = optional_param('sure', '', PARAM_ALPHA); +$move = optional_param('move', '', PARAM_ALPHA); +$type = optional_param('type', '', PARAM_ALPHA); $display = true; // fall through to normal display @@ -37,18 +39,18 @@ if (!empty($edit) || !empty($new)) { if (!empty($edit)) { - $instance = repository_get_instance($edit); - $configs = $instance->get_option_names(); - $plugin = $instance->type; - $typeid = $instance->typeid; + $repositorytype = repository_get_type_by_typename($edit); + $classname = 'repository_' . $repositorytype->get_typename(); + $configs = call_user_func(array($classname,'get_admin_option_names')); + $plugin = $repositorytype->get_typename(); } else { $plugin = $new; $typeid = $new; - $instance = null; + $repositorytype = null; } $CFG->pagepath = 'admin/managerepository/' . $plugin; // display the edit form for this instance - $mform = new repository_admin_form('', array('plugin' => $plugin, 'typeid'=> $typeid, 'instance' => $instance)); + $mform = new repository_admin_form('', array('plugin' => $plugin, 'instance' => $repositorytype)); // end setup, begin output if ($mform->is_cancelled()){ @@ -60,14 +62,16 @@ } if ($edit) { $settings = array(); - $settings['name'] = $fromform->name; foreach($configs as $config) { $settings[$config] = $fromform->$config; } - $success = $instance->set_option($settings); + $success = $repositorytype->update_options($settings); } else { - $success = repository_static_function($plugin, 'create', $plugin, 0, get_system_context(), $fromform); + $type = new repository_type($plugin,(array)$fromform); + $type->create(); + $success = true; $data = data_submitted(); + } if ($success) { $savedstr = get_string('configsaved', 'repository'); @@ -85,23 +89,29 @@ $mform->display(); print_simple_box_end(); $return = false; + + //display instances list and creation form + if ($edit){ + repository_display_instances_list(get_context_instance(CONTEXT_SYSTEM), true, $edit); + } + } } else if (!empty($hide)) { if (!confirm_sesskey()) { print_error('confirmsesskeybad', '', $baseurl); } - $instance = repository_get_instance($hide); - $instance->hide(); + $repositorytype = repository_get_type_by_typename($hide); + $repositorytype->switch_and_update_visibility(); $return = true; } else if (!empty($delete)) { admin_externalpage_print_header(); - $instance = repository_get_instance($delete); + $repositorytype = repository_get_type_by_typename($delete); if ($sure) { if (!confirm_sesskey()) { print_error('confirmsesskeybad', '', $baseurl); } - if ($instance->delete()) { - $deletedstr = get_string('instancedeleted', 'repository'); + if ($repositorytype->delete()) { + $deletedstr = get_string('removed', 'repository'); print_heading($deletedstr); redirect($baseurl, $deletedstr, 3); } else { @@ -109,10 +119,13 @@ } exit; } - notice_yesno(get_string('confirmdelete', 'repository', $instance->name), $sesskeyurl . '&delete=' . $delete . '&sure=yes', $baseurl); + notice_yesno(get_string('confirmremove', 'repository', $repositorytype->get_readablename()), $sesskeyurl . '&delete=' . $delete . '&sure=yes', $baseurl); $return = false; } - +else if (!empty($move) && !empty($type)) { + $repositorytype = repository_get_type_by_typename($type); + $repositorytype->move_order($move); +} if (!empty($return)) { redirect($baseurl); diff --git a/admin/repositoryinstance.php b/admin/repositoryinstance.php new file mode 100644 index 0000000000000..e2f19d485bd98 --- /dev/null +++ b/admin/repositoryinstance.php @@ -0,0 +1,128 @@ +dirroot . '/repository/lib.php'); +require_once($CFG->libdir . '/adminlib.php'); + +// id of repository +$edit = optional_param('edit', 0, PARAM_INT); +$new = optional_param('new', '', PARAM_FORMAT); +$hide = optional_param('hide', 0, PARAM_INT); +$delete = optional_param('delete', 0, PARAM_INT); +$sure = optional_param('sure', '', PARAM_ALPHA); +$move = optional_param('move', '', PARAM_ALPHA); +$type = optional_param('type', '', PARAM_ALPHA); + +$display = true; // fall through to normal display + +$pagename = 'repositorycontroller'; + +if ($delete) { + $pagename = 'repositorydelete'; +} else if ($new) { + $pagename = 'repositorynew'; +} + +admin_externalpage_setup($pagename); +require_login(SITEID, false); +require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)); + +$sesskeyurl = $CFG->wwwroot . '/' . $CFG->admin . '/repositoryinstance.php?sesskey=' . sesskey(); +$baseurl = $CFG->wwwroot . '/admin/repository.php?session='. sesskey() .'&edit='; +if ($new) { + $baseurl .= $new; +} +else { + $baseurl .= $type; +} +$configstr = get_string('managerepositories', 'repository'); + +$return = true; + +if (!empty($edit) || !empty($new)) { + if (!empty($edit)) { + $instance = repository_get_instance($edit); + $instancetype = repository_get_type_by_id($instance->typeid); + $classname = 'repository_' . $instancetype->get_typename(); + $configs = $instance->get_instance_option_names(); + $plugin = $instancetype->get_typename(); + $typeid = $instance->typeid; + } else { + $plugin = $new; + $typeid = $new; + $instance = null; + } + + // display the edit form for this instance + $mform = new repository_instance_form('', array('plugin' => $plugin, 'typeid' => $typeid,'instance' => $instance)); + // end setup, begin output + + if ($mform->is_cancelled()){ + redirect($baseurl); + exit; + } else if ($fromform = $mform->get_data()){ + if (!confirm_sesskey()) { + print_error('confirmsesskeybad', '', $baseurl); + } + if ($edit) { + $settings = array(); + $settings['name'] = $fromform->name; + foreach($configs as $config) { + $settings[$config] = $fromform->$config; + } + $success = $instance->set_option($settings); + } else { + $success = repository_static_function($plugin, 'create', $plugin, 0, get_system_context(), $fromform); + $data = data_submitted(); + } + if ($success) { + $savedstr = get_string('configsaved', 'repository'); + admin_externalpage_print_header(); + print_heading($savedstr); + redirect($baseurl, $savedstr, 3); + } else { + print_error('instancenotsaved', 'repository', $baseurl); + } + exit; + } else { + admin_externalpage_print_header(); + print_heading(get_string('configplugin', 'repository_'.$plugin)); + print_simple_box_start(); + $mform->display(); + print_simple_box_end(); + $return = false; + } +} else if (!empty($hide)) { + if (!confirm_sesskey()) { + print_error('confirmsesskeybad', '', $baseurl); + } + $instance = repository_get_type_by_typename($hide); + var_dump($instance); + var_dump($hide); + $instance->hide(); + $return = true; +} else if (!empty($delete)) { + admin_externalpage_print_header(); + $instance = repository_get_instance($delete); + if ($sure) { + if (!confirm_sesskey()) { + print_error('confirmsesskeybad', '', $baseurl); + } + if ($instance->delete()) { + $deletedstr = get_string('instancedeleted', 'repository'); + print_heading($deletedstr); + redirect($baseurl, $deletedstr, 3); + } else { + print_error('instancenotdeleted', 'repository', $baseurl); + } + exit; + } + notice_yesno(get_string('confirmdelete', 'repository', $instance->name), $sesskeyurl . '&type=' . $type . '&delete=' . $delete . '&sure=yes', $CFG->wwwroot . '/admin/repositoryinstance.php?session='. sesskey()); + $return = false; +} + +if (!empty($return)) { + + redirect($baseurl); +} +admin_externalpage_print_footer(); \ No newline at end of file diff --git a/admin/settings/plugins.php b/admin/settings/plugins.php index 99b3e879e1d42..4bfb0a8150caf 100644 --- a/admin/settings/plugins.php +++ b/admin/settings/plugins.php @@ -194,14 +194,17 @@ $ADMIN->add('repositorysettings', new admin_externalpage('repositorycontroller', get_string('managerepositories', 'repository'), $url, 'moodle/site:config', true), '', $url); - foreach (repository_get_instances(get_context_instance(CONTEXT_SYSTEM), null, false) - as $repository) + foreach (repository_get_types() + as $repositorytype) { - if ($repository->has_admin_config()) { + //display setup page for plugins with: general options or instance options or multiple instances + if (repository_static_function($repositorytype->get_typename(), 'has_admin_config') + || repository_static_function($repositorytype->get_typename(), 'has_instance_config') + || repository_static_function($repositorytype->get_typename(), 'has_multiple_instances')) { $ADMIN->add('repositorysettings', - new admin_externalpage('repositorysettings'.$repository->id, - $repository->name, - $url . '?edit=' . $repository->id), + new admin_externalpage('repositorysettings'.$repositorytype->get_typename(), + $repositorytype->get_readablename(), + $url . '?edit=' . $repositorytype->get_typename()), 'moodle/site:config'); } } diff --git a/blocks/admin/block_admin.php b/blocks/admin/block_admin.php index 5f3b07240c095..f5821194087fc 100644 --- a/blocks/admin/block_admin.php +++ b/blocks/admin/block_admin.php @@ -186,11 +186,16 @@ function get_content() { } } + /// Repository Account + if ($course->id !== SITEID) { + $this->content->items[]=''.get_string('repositories').''; + $this->content->icons[]=''; + } /// Manage files if ($course->id !== SITEID and has_capability('moodle/course:managefiles', $context)) { $this->content->items[]=''.get_string('files').''; - $this->content->icons[]=''; + $this->content->icons[]=''; } /// Authorize hooks diff --git a/lang/en_utf8/moodle.php b/lang/en_utf8/moodle.php index 113578612401e..f331970f7f73c 100644 --- a/lang/en_utf8/moodle.php +++ b/lang/en_utf8/moodle.php @@ -1253,6 +1253,7 @@ $string['renamefileto'] = 'Rename $a to'; $string['report'] = 'Report'; $string['reports'] = 'Reports'; +$string['repositories'] = 'Repositories'; $string['requestcourse'] = 'Request a course'; $string['requestedby'] = 'Requested by'; $string['requestreason'] = 'Reason for course request'; diff --git a/lang/en_utf8/repository.php b/lang/en_utf8/repository.php index 9297aa77eb6cd..0831d0a4b2b93 100644 --- a/lang/en_utf8/repository.php +++ b/lang/en_utf8/repository.php @@ -1,5 +1,6 @@ ' . + $return = '
' . '' . ' ' . $selecthtml . + $return = '
' . $selecthtml . ' ' . @@ -3880,7 +3880,7 @@ function output_html($data, $query='') { } $return .= ' \n"; } $return .= "
\n"; @@ -5567,8 +5567,8 @@ function is_related($query) { return true; } } - foreach (repository_get_instances(get_context_instance(CONTEXT_SYSTEM), null, false) as $instance) { - $title = $instance->name; + foreach (repository_get_types() as $instance) { + $title = $instance->get_typename(); if (strpos($textlib->strtolower($title), $query) !== false) { return true; } @@ -5580,32 +5580,67 @@ function output_html($data, $query='') { global $CFG, $USER; $output = print_simple_box_start(true); $namestr = get_string('name'); - $pluginstr = get_string('plugin', 'repository'); $stropt = get_string('operation', 'repository'); + $updown = get_string('updown', 'repository'); $plugins = get_list_of_plugins('repository'); - $instances = repository_get_instances(get_context_instance(CONTEXT_SYSTEM), null, false); + $instances = repository_get_types(); + $instancesnumber = count($instances); + $alreadyplugins = array(); $table = new StdClass; - $table->head = array($namestr, $pluginstr, $stropt); + $table->head = array($namestr, $updown, $stropt); + $table->align = array('left', 'center', 'center'); $table->data = array(); + $updowncount=1; foreach ($instances as $i) { $row = ''; - $row .= '' . get_string('edit') . '' . "\n"; - $row .= '' . get_string('delete') . '' . "\n"; - $row .= ' ' . get_string($i->visible ? 'hide' : 'show') . '' . "\n"; - $table->data[] = array($i->name, $i->type, $row); + //display edit link only if you can config the type or its instances + if ( repository_static_function($i->get_typename(), 'has_admin_config') + || repository_static_function($i->get_typename(), 'has_instance_config') + || repository_static_function($i->get_typename(), 'has_multiple_instances')) { + $row .= '' . get_string('edit') . '' . "\n"; + } + $row .= '' . get_string('delete') . '' . "\n"; + $row .= ' ' . get_string($i->get_visible() ? 'hide' : 'show') . '' . "\n"; + + // display up/down link + $updown = ''; + + if ($updowncount > 1) { + $updown .= "baseurl&move=up&type=".$i->get_typename()."\">"; + $updown .= "pixpath}/t/up.gif\" alt=\"up\" /> "; + } + else { + $updown .= "pixpath}/spacer.gif\" class=\"icon\" alt=\"\" /> "; + } + if ($updowncount < count($instances)) { + $updown .= "baseurl&move=down&type=".$i->get_typename()."\">"; + $updown .= "pixpath}/t/down.gif\" alt=\"down\" />"; + } + else { + $updown .= "pixpath}/spacer.gif\" class=\"icon\" alt=\"\" />"; + } + + $updowncount++; + + $table->data[] = array($i->get_readablename(), $updown,$row); + if (!in_array($i->get_typename(), $alreadyplugins)) { + $alreadyplugins[] = $i->get_typename(); + } } $output .= print_table($table, true); $instancehtml = '

'; $addable = 0; - $instancehtml .= get_string('createrepository', 'repository'); + $instancehtml .= get_string('addplugin', 'repository'); $instancehtml .= '

'; diff --git a/pix/i/repository.png b/pix/i/repository.png new file mode 100644 index 0000000000000..1ba8f47609e79 Binary files /dev/null and b/pix/i/repository.png differ diff --git a/repository/boxnet/repository.class.php b/repository/boxnet/repository.class.php index aa80928a91953..48e6aab842593 100755 --- a/repository/boxnet/repository.class.php +++ b/repository/boxnet/repository.class.php @@ -168,20 +168,41 @@ public function print_login(){ public function print_search(){ return false; } + public static function has_admin_config() { return true; } + + public static function has_instance_config() { + return true; + } + + public static function has_multiple_instances(){ + return true; + } + + public static function get_admin_option_names(){ + return array('api_key'); + } + + public static function get_instance_option_names(){ + return array('share_url'); + } + public function admin_config_form(&$mform) { + $public_account = get_config('boxnet', 'public_account'); $api_key = get_config('boxnet', 'api_key'); if (empty($api_key)) { $api_key = ''; } $strrequired = get_string('required'); - $mform->addElement('text', 'api_key', get_string('apikey', 'repository_boxnet'), array('value'=>$api_key)); + $mform->addElement('text', 'api_key', get_string('apikey', 'repository_boxnet'), array('value'=>$api_key,'size' => '40')); $mform->addRule('api_key', $strrequired, 'required', null, 'client'); } - public static function get_option_names(){ - return array('api_key'); + + public function instance_config_form(&$mform) { + $share_url = get_config('boxnet', 'share_url'); + $mform->addElement('text', 'share_url', get_string('shareurl', 'repository_boxnet'), array('value'=>$share_url)); } } diff --git a/repository/flickr/repository.class.php b/repository/flickr/repository.class.php index 948c662f32d02..c5f1816782bee 100755 --- a/repository/flickr/repository.class.php +++ b/repository/flickr/repository.class.php @@ -232,16 +232,18 @@ public function get_file($photo_id, $file = ''){ public static function has_admin_config() { return true; } + public function admin_config_form(&$mform) { $api_key = get_config('flickr', 'api_key'); if (empty($api_key)) { $api_key = ''; } $strrequired = get_string('required'); - $mform->addElement('text', 'api_key', get_string('apikey', 'repository_boxnet'), array('value'=>$api_key)); + $mform->addElement('text', 'api_key', get_string('apikey', 'repository_boxnet'), array('value'=>$api_key,'size' => '40')); $mform->addRule('api_key', $strrequired, 'required', null, 'client'); } - public static function get_option_names(){ + public static function get_admin_option_names(){ return array('api_key'); } + } diff --git a/repository/lib.php b/repository/lib.php index 5f3f1f1c4c149..75f253f578d89 100644 --- a/repository/lib.php +++ b/repository/lib.php @@ -34,11 +34,7 @@ * * See an example of use of this library in repository/boxnet/repository.class.php * - * A few notes : - * // options are stored as serialized format in database - * $options = array('api_key'=>'dmls97d8j3i9tn7av8y71m9eb55vrtj4', - * 'auth_token'=>'', 'path_root'=>'/'); - * $repo = new repository_xxx($options); + * A few notes: * // print login page or a link to redirect to another page * $repo->print_login(); * // call get_listing, and print result @@ -54,6 +50,356 @@ require_once(dirname(dirname(__FILE__)).'/lib/filelib.php'); require_once(dirname(dirname(__FILE__)).'/lib/formslib.php'); +/** + * A repository_type is a repository plug-in. It can be Box.net, Flick-r, ... + * A repository type can be edited, sorted and hidden. It is mandatory for an + * administrator to create a repository type in order to be able to create + * some instances of this type. + * + * Coding note: + * - a repository_type object is mapped to the "repository" database table + * - "typename" attibut maps the "type" database field. It is unique. + * - general "options" for a repository type are saved in the config_plugin table + * - TODO: when you delete a repository, all instances are deleted + * - When you create a type for a plugin that can't have multiple instances, a + * instance is automatically created. + */ +class repository_type { + + + /** + * Type name (no whitespace) - A type name is unique + * Note: for a user-friendly type name see get_readablename() + * @var String + */ + private $_typename; + + + /** + * Options of this type + * They are general options that any instance of this type would share + * e.g. API key + * These options are saved in config_plugin table + * @var array + */ + private $_options; + + + /** + * Is the repository type visible or hidden + * If false (hidden): no instances can be created, edited, deleted, showned , used... + * @var boolean + */ + private $_visible; + + + /** + * 0 => not ordered, 1 => first position, 2 => second position... + * A not order type would appear in first position (should never happened) + * @var integer + */ + private $_sortorder; + + /** + * repository_type constructor + * @global $CFG + * @param integer $typename + * @param array $typeoptions + * @param boolean $visible + * @param integer $sortorder (don't really need set, it will be during create() call) + */ + public function __construct($typename = '', $typeoptions = array(), $visible = true, $sortorder = 0){ + global $CFG; + + //set type attributs + $this->_typename = $typename; + $this->_visible = $visible; + $this->_sortorder = $sortorder; + + //set options attribut + $this->_options = array(); + //check that the type can be setup + if (repository_static_function($typename,"has_admin_config")){ + $options = repository_static_function($typename,'get_admin_option_names'); + //set the type options + foreach ($options as $config) { + if (array_key_exists($config,$typeoptions)){ + $this->_options[$config] = $typeoptions[$config]; + } + } + } + } + + /** + * Get the type name (no whitespace) + * For a human readable name, use get_readablename() + * @return String the type name + */ + public function get_typename(){ + return $this->_typename; + } + + /** + * Return a human readable and user-friendly type name + * @return string user-friendly type name + */ + public function get_readablename(){ + return get_string('repositoryname','repository_'.$this->_typename); + } + + /** + * Return general options + * @return array the general options + */ + public function get_options(){ + return $this->_options; + } + + /** + * Return visibility + * @return boolean + */ + public function get_visible(){ + return $this->_visible; + } + + /** + * Return order / position of display in the file picker + * @return integer + */ + public function get_sortorder(){ + return $this->_sortorder; + } + + /** + * Create a repository type (the type name must not already exist) + * @global object $DB + */ + public function create(){ + global $DB; + + //check that $type has been set + $timmedtype = trim($this->_typename); + if (empty($timmedtype)) { + throw new repository_exception('emptytype', 'repository'); + } + + //set sortorder as the last position in the list + if (!isset($this->_sortorder) || $this->_sortorder == 0 ){ + $sql = "SELECT MAX(sortorder) FROM {repository}"; + $this->_sortorder = 1 + $DB->get_field_sql($sql); + } + + //only create a new type if it doesn't already exist + $existingtype = $DB->get_record('repository', array('type'=>$this->_typename)); + if(!$existingtype){ + //create the type + $newtype = new stdclass; + $newtype->type = $this->_typename; + $newtype->visible = $this->_visible; + $newtype->sortorder = $this->_sortorder; + $DB->insert_record('repository', $newtype); + + //save the options in DB + $this->update_options(); + } + else { + throw new repository_exception('existingrepository', 'repository'); + } + } + + + /** + * Update plugin options into the config_plugin table + * @param array $options + * @return boolean + */ + public function update_options($options = null){ + if (!empty($options)){ + $this->_options = $options; + } + + foreach ($this->_options as $name => $value) { + set_config($name,$value,$this->_typename); + } + + return true; + } + + /** + * Update visible database field with the value given as parameter + * or with the visible value of this object + * This function is private. + * For public access, have a look to switch_and_update_visibility() + * @global object $DB + * @param boolean $visible + * @return boolean + */ + private function update_visible($visible = null){ + global $DB; + + if (!empty($visible)){ + $this->_visible = $visible; + } + else if (!isset($this->_visible)){ + throw new repository_exception('updateemptyvisible', 'repository'); + } + + return $DB->set_field('repository', 'visible', $this->_visible, array('type'=>$this->_typename)); + } + + /** + * Update database sortorder field with the value given as parameter + * or with the sortorder value of this object + * This function is private. + * For public access, have a look to move_order() + * @global object $DB + * @param integer $sortorder + * @return boolean + */ + private function update_sortorder($sortorder = null){ + global $DB; + + if (!empty($sortorder) && $sortorder!=0){ + $this->_sortorder = $sortorder; + } + //if sortorder is not set, we set it as the ;ast position in the list + else if (!isset($this->_sortorder) || $this->_sortorder == 0 ){ + $sql = "SELECT MAX(sortorder) FROM {repository}"; + $this->_sortorder = 1 + $DB->get_field_sql($sql); + } + + return $DB->set_field('repository', 'sortorder', $this->_sortorder, array('type'=>$this->_typename)); + } + + /** + * Change order of the type with its adjacent upper or downer type + * (database fields are updated) + * Algorithm details: + * 1. retrieve all types in an array. This array is sorted by sortorder, + * and the array keys start from 0 to X (incremented by 1) + * 2. switch sortorder values of this type and its adjacent type + * @global object $DB + * @param string $move "up" or "down" + */ + public function move_order($move) { + global $DB; + //retrieve all types + $types = repository_get_types(); + + //retrieve this type into the returned array + $i = 0; + while (!isset($indice) && $iget_typename() == $this->_typename){ + $indice = $i; + } + $i++; + } + + //retrieve adjacent indice + switch ($move) { + case "up": + $adjacentindice = $indice - 1; + break; + case "down": + $adjacentindice = $indice + 1; + break; + default: + throw new repository_exception('movenotdefined', 'repository'); + } + + //switch sortorder of this type and the adjacent type + //TODO: we could reset sortorder for all types. This is not as good in performance term, but + //that prevent from wrong behaviour on a screwed database. As performance are not important in this particular case + //it worth to change the algo. + if ($adjacentindice>=0 && !empty($types[$adjacentindice])){ + $DB->set_field('repository', 'sortorder', $this->_sortorder, array('type'=>$types[$adjacentindice]->get_typename())); + $this->update_sortorder($types[$adjacentindice]->get_sortorder()); + } + } + + /** + * 1. Switch the visibility OFF if it's ON, and ON if it's OFF. + * 2. Update the type + * @return + */ + public function switch_and_update_visibility(){ + $this->_visible = !$this->_visible; + return $this->update_visible(); + } + + + /** + * Delete a repository_type - DO NOT CALL IT TILL THE TODO IS DONE + * TODO: delete all instances for this type + * @global object $DB + * @return boolean + */ + public function delete(){ + global $DB; + return $DB->delete_records('repository', array('type' => $this->_typename)); + } +} + +/** + * Return a type for a given type name. + * @global object $DB + * @param string $typename the type name + * @return integer + */ +function repository_get_type_by_typename($typename){ + global $DB; + + if(!$record = $DB->get_record('repository',array('type' => $typename))) { + return false; + } + + return new repository_type($typename, (array)get_config($typename), $record->visible, $record->sortorder); +} + +/** + * Return a type for a given type id. + * @global object $DB + * @param string $typename the type name + * @return integer + */ +function repository_get_type_by_id($id){ + global $DB; + + if(!$record = $DB->get_record('repository',array('id' => $id))) { + return false; + } + + return new repository_type($record->type, (array)get_config($record->type), $record->visible, $record->sortorder); +} + +/** + * Return all repository types ordered by sortorder + * first type in returnedarray[0], second type in returnedarray[1], ... + * @global object $DB + * @return array Repository types + */ +function repository_get_types(){ + global $DB; + + $types = array(); + + if($records = $DB->get_records('repository',null,'sortorder')) { + foreach($records as $type) { + $typename = $type->type; + $visible = $type->visible; + $sortorder = $type->sortorder; + $types[] = new repository_type($typename, (array)get_config($typename), $visible, $sortorder); + } + } + + return $types; +} + +/** + *TODO: write comment + */ + abstract class repository { public $id; public $context; @@ -245,8 +591,8 @@ final public static function create($type, $userid, $context, $params) { $record->contextid = $context->id; $record->userid = $userid; $id = $DB->insert_record('repository_instances', $record); - if (call_user_func($classname . '::has_admin_config')) { - $configs = call_user_func($classname . '::get_option_names'); + if (call_user_func($classname . '::has_instance_config')) { + $configs = call_user_func($classname . '::get_instance_option_names'); $options = array(); foreach ($configs as $config) { $options[$config] = $params[$config]; @@ -451,20 +797,56 @@ abstract public function print_login(); abstract public function print_search(); /** - * TODO: write comment + * Defines operations that happen occasionally on cron * @return */ + public function cron() { + return true; + } + + /** + * Return true if the plugin type has at least one general option field + * By default: false + * @return boolean + */ public static function has_admin_config() { return false; } + /** + * Return true if a plugin instance has at least one config field + * By default: false + * @return boolean + */ + public static function has_instance_config() { + return false; + } /** - * Defines operations that happen occasionally on cron - * @return + * Return true if the plugin can have multiple instances + * By default: false + * @return boolean */ - public function cron() { - return true; + public static function has_multiple_instances(){ + return false; + } + + /** + * Return names of the general options + * By default: no general option name + * @return array + */ + public static function get_admin_option_names(){ + return array(); + } + + /** + * Return names of the instance options + * By default: no instance option name + * @return array + */ + public static function get_instance_option_names(){ + return array(); } } @@ -484,9 +866,10 @@ class repository_exception extends moodle_exception { * @param integer $userid * @param boolean $visible if visible == true, return visible instances only, * otherwise, return all instances + * @param string $type a type name to retrieve * @return array repository instances */ -function repository_get_instances($context, $userid = null, $visible = true){ +function repository_get_instances($context, $userid = null, $visible = true, $type=null){ global $DB, $CFG, $USER; $params = array(); $sql = 'SELECT i.*, r.type AS repositorytype, r.visible FROM {repository} r, {repository_instances} i WHERE '; @@ -506,6 +889,10 @@ function repository_get_instances($context, $userid = null, $visible = true){ if($visible == true) { $sql .= ' AND (r.visible = 1)'; } + if(isset($type)) { + $sql .= ' AND (r.type = ?)'; + $params[] = $type; + } if(!$repos = $DB->get_records_sql($sql, $params)) { $repos = array(); } @@ -553,11 +940,20 @@ function repository_get_instance($id){ * @global $CFG * @param $plugin * @param $function + * @param type $nocallablereturnvalue default value if function not found + * it's mostly used when you don't want to display an error but + * return a boolean * @return */ function repository_static_function($plugin, $function) { global $CFG; + //check that the plugin exists + $typedirectory = $CFG->dirroot . '/repository/'. $plugin . '/repository.class.php'; + if (!file_exists($typedirectory)) { + throw new repository_exception('invalidplugin', 'repository'); + } + $pname = null; if (is_object($plugin) || is_array($plugin)) { $plugin = (object)$plugin; @@ -575,7 +971,7 @@ function repository_static_function($plugin, $function) { array_shift($args); } - require_once($CFG->dirroot . '/repository/' . $plugin . '/repository.class.php'); + require_once($typedirectory); return call_user_func_array(array('repository_' . $plugin, $function), $args); } @@ -1427,7 +1823,7 @@ function openpicker_$suffix(params) { /** * TODO: write comment */ -final class repository_admin_form extends moodleform { +final class repository_instance_form extends moodleform { protected $instance; protected $plugin; @@ -1456,19 +1852,20 @@ public function definition() { $mform->addRule('name', $strrequired, 'required', null, 'client'); // let the plugin add the fields they want (either statically or not) - if (repository_static_function($this->plugin, 'has_admin_config')) { + if (repository_static_function($this->plugin, 'has_instance_config')) { if (!$this->instance) { - $result = repository_static_function($this->plugin, 'admin_config_form', $mform); + $result = repository_static_function($this->plugin, 'instance_config_form', $mform); } else { - $result = $this->instance->admin_config_form($mform); + $result = $this->instance->instance_config_form($mform); } } // and set the data if we have some. + //var_dump($this); if ($this->instance) { $data = array(); $data['name'] = $this->instance->name; - foreach ($this->instance->get_option_names() as $config) { + foreach ($this->instance->get_instance_option_names() as $config) { if (!empty($this->instance->$config)) { $data[$config] = $this->instance->$config; } else { @@ -1506,3 +1903,148 @@ public function validation($data) { return $errors; } } + + +/** + * Display a form with the general option fields of a type + */ +final class repository_admin_form extends moodleform { + protected $instance; + protected $plugin; + + /** + * Definition of the moodleform + * @global object $CFG + */ + public function definition() { + global $CFG; + // type of plugin, string + $this->plugin = $this->_customdata['plugin']; + $this->instance = (isset($this->_customdata['instance']) + && is_a($this->_customdata['instance'], 'repository_type')) + ? $this->_customdata['instance'] : null; + + $mform =& $this->_form; + $strrequired = get_string('required'); + + $mform->addElement('hidden', 'edit', ($this->instance) ? $this->instance->get_typename() : 0); + $mform->addElement('hidden', 'new', $this->plugin); + $mform->addElement('hidden', 'plugin', $this->plugin); + + // let the plugin add the fields they want (either statically or not) + if (repository_static_function($this->plugin, 'has_admin_config')) { + if (!$this->instance) { + $result = repository_static_function($this->plugin, 'admin_config_form', $mform); + } else { + $classname = 'repository_' . $this->instance->get_typename(); + $result = call_user_func(array($classname,'admin_config_form'),$mform); + } + } + + // and set the data if we have some. + if ($this->instance) { + $data = array(); + $option_names = call_user_func(array($classname,'get_admin_option_names')); + $instanceoptions = $this->instance->get_options(); + foreach ($option_names as $config) { + if (!empty($instanceoptions[$config])) { + $data[$config] = $instanceoptions[$config]; + } else { + $data[$config] = ''; + } + } + $this->set_data($data); + } + + $this->add_action_buttons(true, get_string('submit')); + } + +} + + +/** + * Display a repository instance list (with edit/delete/create links) + * @global object $CFG + * @global object $USER + * @param object $context the context for which we display the instance + * @param boolean $admin if true, so the form is been called by an administration + * page, only one type would be displayed + * @param string $typename if set, we display only one type of instance + */ +function repository_display_instances_list($context, $admin = false, $typename = null){ + global $CFG, $USER; + if ($admin) { + $baseurl = $CFG->wwwroot . '/admin/repositoryinstance.php?sesskey=' . sesskey(); + $type = repository_get_type_by_typename($typename); + + } + $output = print_simple_box_start(true); + $output .= "

" . get_string('instances', 'repository') . "

"; + + $namestr = get_string('name'); + $pluginstr = get_string('plugin', 'repository'); + $stropt = get_string('operation', 'repository'); + $updown = get_string('updown', 'repository'); + $plugins = get_list_of_plugins('repository'); + $instances = repository_get_instances($context,null,true,$typename); + $instancesnumber = count($instances); + $alreadyplugins = array(); + $table = new StdClass; + $table->head = array($namestr, $pluginstr, $stropt); + $table->align = array('left', 'left', 'center'); + $table->data = array(); + $updowncount=1; + foreach ($instances as $i) { + $row = ''; + $row .= '' . get_string('edit') . '' . "\n"; + $row .= '' . get_string('delete') . '' . "\n"; + //$row .= ' ' . get_string($i->visible ? 'hide' : 'show') . '' . "\n"; + + $table->data[] = array($i->name, $type->get_readablename(),$row); + if (!in_array($i->name, $alreadyplugins)) { + $alreadyplugins[] = $i->name; + } + } + $output .= print_table($table, true); + $instancehtml = '

'; + $addable = 0; + $instancehtml .= get_string('createrepository', 'repository'); + $instancehtml .= '

'; + + if ($addable) { + $instancehtml .= '
'; + $output .= $instancehtml; + } + + $output .= print_simple_box_end(true); + + //print the list + creation links + print($output); + +} diff --git a/repository/local/repository.class.php b/repository/local/repository.class.php index 58891e3ad7e4e..a3b5f314a68e7 100755 --- a/repository/local/repository.class.php +++ b/repository/local/repository.class.php @@ -165,10 +165,10 @@ public function print_search() { } public static function has_admin_config() { - return true; + return false; } - public static function get_option_names() { + public static function get_admin_option_names() { // todo: add dynamic loading threshold return array(); } diff --git a/repository/upload/repository.class.php b/repository/upload/repository.class.php index ae61b90527a63..bd937427fc015 100755 --- a/repository/upload/repository.class.php +++ b/repository/upload/repository.class.php @@ -50,7 +50,7 @@ public static function has_admin_config() { return true; } - public static function get_option_names() { + public static function get_admin_option_names() { return array(); }