Commit e4ed04ab authored by Penny Leach's avatar Penny Leach Committed by Nigel McNie

very broken commit so I can merge with origin

parent 9e9dbab6
......@@ -46,20 +46,11 @@ if ($install) {
$message = '';
if (!get_config('installed')) {
try {
$exceptions = core_install_defaults();
core_install_defaults();
}
catch (SQLException $e) {
json_reply('local', $e->getMessage());
}
catch (TemplateParserException $e) {
$message = '<a href="' . get_config('wwwroot') .'admin/extensions/templates.php">'
. get_string('fixtemplatescontinue', 'admin') . '</a>';
}
if (is_array($exceptions) && count($exceptions) > 0) {
// these ones are non fatal...
$message = '<a href="' . get_config('wwwroot') .'admin/extensions/templates.php">'
. get_string('fixtemplatescontinue', 'admin') . '</a>';
}
}
json_reply(false, $message);
}
......
......@@ -37,6 +37,10 @@ class PluginArtefactBlog extends PluginArtefact {
'blogpost',
);
}
public static function get_block_types() {
return array();
}
public static function get_plugin_name() {
return 'blog';
......@@ -53,10 +57,6 @@ class PluginArtefactBlog extends PluginArtefact {
);
}
public static function get_toplevel_artefact_types() {
return array('blog');
}
public static function get_cron() {
return array(
(object)array(
......
......@@ -35,6 +35,10 @@ class PluginArtefactFile extends PluginArtefact {
'image',
);
}
public static function get_block_types() {
return array();
}
public static function get_plugin_name() {
return 'file';
......@@ -72,9 +76,6 @@ class PluginArtefactFile extends PluginArtefact {
update_record('usr', array('quota' => get_config_plugin('artefact', 'file', 'defaultquota')), array('id' => $user['id']));
}
public static function get_toplevel_artefact_types() {
return array('file');
}
public static function sort_child_data($a, $b) {
if ($a->container && !$b->container) {
......
......@@ -58,6 +58,10 @@ class PluginArtefactInternal extends PluginArtefact {
'profileicon'
);
}
public static function get_block_types() {
return array();
}
public static function get_plugin_name() {
return 'internal';
......@@ -100,10 +104,6 @@ class PluginArtefactInternal extends PluginArtefact {
delete_records_select('artefact_internal_profile_email', 'verified=0 AND expiry IS NOT NULL AND expiry < ?', array(db_format_timestamp(time())));
}
public static function get_toplevel_artefact_types() {
return array('profile');
}
public static function sort_child_data($a, $b) {
return strnatcasecmp($a->text, $b->text);
}
......
......@@ -41,6 +41,17 @@ abstract class PluginArtefact extends Plugin {
*/
public static abstract function get_artefact_types();
/**
* This function returns a list of classnames
* of block types this plugin provides
* they must match directories inside artefact/$name/blocktype
* @abstract
* @return array
*/
public static abstract function get_block_types();
/**
* This function returns the name of the plugin.
* @abstract
......@@ -49,11 +60,6 @@ abstract class PluginArtefact extends Plugin {
public static abstract function get_plugin_name();
/**
* Gets a list of top level artefact types, used in the view creation wizard
*/
public static abstract function get_toplevel_artefact_types();
/**
* This function returns an array of menu items
* to be displayed
......@@ -384,77 +390,11 @@ abstract class ArtefactType {
}
/**
* render instance to given format. This function simply switches and
* calls one of listself(), listchildren(), render_metadata() or
* render_full(). If a format it doesn't know about is passed in, it
* throws an exception. You should only need to override this if you have
* invented some kind of new format.
*
* @param int $format format type (constant)
* @param array $options options for format
*/
public function render($format, $options) {
switch ($format) {
case FORMAT_ARTEFACT_LISTSELF:
return $this->listself($options);
case FORMAT_ARTEFACT_RENDERMETADATA:
return $this->render_metadata($options);
case FORMAT_ARTEFACT_LISTCHILDREN:
return $this->listchildren($options);
case FORMAT_ARTEFACT_RENDERFULL:
return $this->render_full($options);
default:
//@todo: This should be an invalid render format exception
throw new Exception('invalid render format');
}
}
protected function get_metadata($options) {
$data = array('title' => $this->get('title'),
'type' => get_string($this->get('artefacttype'), 'artefact.' . $this->get_plugin_name()),
'owner' => display_name(optional_userobj($this->get('owner'))),
'created' => format_date($this->get('ctime')),
'lastmodified' => format_date($this->get('mtime')));
foreach ($data as $key => $value) {
$data[$key] = array('name' => get_string($key),
'value' => $value);
}
return $data;
}
/**
* render instance to metadata format
* @param $options
* @todo: get and display artefact size.
*/
protected function render_metadata($options) {
$smarty = smarty();
if (isset($options['viewid'])) {
$smarty->assign('title', '<a href="' . get_config('wwwroot') . 'view/view.php?view=' . $options['viewid'] . '&amp;artefact=' . $this->get('id') . '">'
. $this->get('title') . '</a>');
}
else {
$smarty->assign('title', $this->get('title'));
}
$smarty->assign('type', get_string($this->get('artefacttype'), 'artefact.' . $this->get_plugin_name()));
$smarty->assign('owner', display_name(optional_userobj($this->get('owner'))));
$smarty->assign('nicectime', format_date($this->get('ctime')));
$smarty->assign('nicemtime', format_date($this->get('mtime')));
return array('html' => $smarty->fetch('artefact/render_metadata.tpl'),
'javascript' => null);
}
*
* this function provides the way to link to viewing very deeply nested artefacts
* within a view, it makes urls like view/view.php?id=x&artefact=y
* which is important for the access check.
*/
public function add_to_render_path(&$options) {
if (empty($options['path'])) {
$options['path'] = $this->get('id');
......@@ -465,72 +405,6 @@ abstract class ArtefactType {
}
/**
* list artefact children. There's a default for this, but we only use it
* if the class thinks it can render FORMAT_ARTEFACT_LISTCHILDREN.
*
* @param $options
* @todo: use a smarty template.
*/
protected function listchildren($options) {
if (in_array(FORMAT_ARTEFACT_LISTCHILDREN, $this->get_render_list())) {
$html = '<ul>';
$js = '';
foreach ($this->get_children_instances() as $child) {
$renderedchild = $child->render(FORMAT_ARTEFACT_LISTSELF, $options);
$html .= '<li>' . $renderedchild['html'] . "</li>\n";
$js .= $renderedchild['javascript'] . "\n";
}
$html .= '</ul>';
return array('html' => $html,
'javascript' => $js);
}
throw new Exception('This artefact cannot render to this format.');
}
/**
* render self
* @param array options
*/
protected function listself($options) {
if (isset($options['viewid'])) {
require_once('artefact.php');
if (artefact_in_view($id = $this->get('id'), $options['viewid'])) {
$title = '<a href="' . get_config('wwwroot') . 'view/view.php?view=' . $options['viewid']
. '&artefact=' . $id;
if (!empty($options['path'])) {
$title .= '&path=' . $options['path'];
}
$title .= '">' . $this->title . '</a>';
}
}
if (!isset($title)) {
$title = $this->title;
}
if (!empty($options['size']) && method_exists($this, 'describe_size')) {
$title .= ' (' . $this->describe_size() . ')';
}
if (!empty($options['link']) && method_exists($this, 'linkself')) {
$title .= ' (' . $this->linkself() . ')';
}
return array('html' => $title,
'javascript' => null);
}
/**
* render the artefact in full. This isn't supported by default. You need
* to override this method if your artefact can do this.
*
* @param array
*/
protected function render_full($options) {
// @todo This should be a proper exception of some sort.
throw new Exception('This artefact cannot render to this format.');
}
/**
* By default public feedback can be placed on all artefacts.
* Artefact types which don't want to allow public feedback should
......@@ -571,16 +445,6 @@ abstract class ArtefactType {
// @todo
}
/**
* returns array of formats can render to (constants)
*/
public static function get_render_list() {
return array(
FORMAT_ARTEFACT_LISTSELF,
FORMAT_ARTEFACT_RENDERMETADATA
);
}
/**
* whether a user will have exactly 0 or 1 of this artefact type
* @abstract
......
......@@ -47,6 +47,10 @@ class PluginArtefactResume extends Plugin {
'workskill'
);
}
public static function get_block_types() {
return array('hello');
}
public static function get_plugin_name() {
return 'resume';
......@@ -75,9 +79,6 @@ class PluginArtefactResume extends Plugin {
);
}
public static function get_toplevel_artefact_types() {
return array('resume');
}
}
class ArtefactTypeResume extends ArtefactType {
......
......@@ -52,7 +52,6 @@ $string['upgradesuccess'] = 'Successfully upgraded';
$string['upgradesuccesstoversion'] = 'Successfully upgraded to version ';
$string['upgradefailure'] = 'Failed to upgrade!';
$string['noupgrades'] = 'Nothing to upgrade! You are fully up to date!';
$string['fixtemplatescontinue'] = 'Some view templates failed to install. Continue here for more information and a fix.';
$string['youcanupgrade'] = 'You can upgrade Mahara from %s (%s) to %s (%s)!';
// Admin navigation menu
......@@ -90,8 +89,6 @@ $string['usersearchdescription'] = 'Search all users and perform administrative
$string['pluginadmin'] = 'Plugin Administration';
$string['pluginadmindescription'] = 'Install and configure plugins';
$string['templatesadmin'] = 'Configure View Templates';
$string['templatesadmindescription'] = 'View installed templates to check their validity';
// Site options
$string['allowpublicviews'] = 'Allow public views';
......
......@@ -56,6 +56,13 @@ $string['dbconnfailed'] = 'Mahara could not connect to the application database.
The error received was:
';
// general exception error messages
$string['blocktypenametaken'] = "Block type %s is already taken by another plugin (%s)";
$string['artefacttypenametaken'] = "Artefact type %s is already taken by another plugin (%s)";
$string['classmissing'] = "class %s for type %s in plugin %s was missing";
$string['artefacttypeclassmissing'] = "Artefact types must all implement a class. Missing %s";
$string['artefactpluginmethodmissing'] = "Artefact plugin %s must implement %s and doesn't";
$string['blocktypelibmissing'] = 'Missing lib.php for block %s in artefact plugin %s';
// if you change these next two , be sure to change them in libroot/errors.php
// as they are duplicated there, in the case that get_string was not available.
......
......@@ -828,6 +828,7 @@ $string['country.ye'] = 'Yemen';
$string['country.zm'] = 'Zambia';
$string['country.zw'] = 'Zimbabwe';
// general stuff that doesn't really fit anywhere else
$string['system'] = 'System';
?>
......@@ -27,12 +27,6 @@
defined('INTERNAL') || die();
define('FORMAT_ARTEFACT_LISTSELF', 'listself');
define('FORMAT_ARTEFACT_LISTCHILDREN', 'listchildren');
define('FORMAT_ARTEFACT_RENDERFULL', 'renderfull');
define('FORMAT_ARTEFACT_RENDERMETADATA', 'rendermetadata');
/**
* Given an artefact plugin name, this function will test if
* it's installable or not. If not, InstallationException will be thrown.
......@@ -41,10 +35,13 @@ function artefact_check_plugin_sanity($pluginname) {
$classname = generate_class_name('artefact', $pluginname);
safe_require('artefact', $pluginname);
if (!class_exists($classname)) {
throw new InstallationException("Artefact types must all implement a class. Missing $classname");
throw new InstallationException(get_string('artefacttypeclassmissing', 'error', $classname));
}
if (!is_callable(array($classname, 'get_artefact_types'))) {
throw new InstallationException("Artefact plugin $classname must implement get_artefact_types and doesn't");
throw new InstallationException(get_string('artefactpluginmethodmissing', 'error', $classname, 'get_artefact_types'));
}
if (!is_callable(array($classname, 'get_block_types'))) {
throw new InstallationException(get_string('artefactpluginmethodmissing', 'error', $classname, 'get_block_types'));
}
$types = call_static_method($classname, 'get_artefact_types');
foreach ($types as $type) {
......@@ -52,11 +49,31 @@ function artefact_check_plugin_sanity($pluginname) {
if (get_config('installed')) {
if ($taken = get_record_select('artefact_installed_type', 'name = ? AND plugin != ?',
array($type, $pluginname))) {
throw new InstallationException("type $type is already taken by another plugin (" . $taken->plugin . ")");
throw new InstallationException(get_string('artefacttypenametaken', 'error', $type, $taken->plugin));
}
}
if (!class_exists($typeclassname)) {
throw new InstallationException(get_string('pluginclassmissing', 'error', $typeclassname, $type, $plugin));
}
}
$types = call_static_method($classname, 'get_block_types');
foreach ($types as $type) {
$typeclassname = generate_blocktype_class_name($type);
if (get_config('installed')) {
if ($taken = get_record_select('blocktype_installed', 'name = ?', array($type))) {
throw new InstallationException(get_string('blocktypenametaken', 'error', $type,
((empty($taken->plugin)) ? $taken->plugin : get_string('system'))));
}
}
// go look for the lib file to include
try {
safe_require('blocktype', $type);
}
catch (Exception $_e) {
throw new InstallationException(get_string('blocktypelibmissing', 'error', $type, $pluginname));
}
if (!class_exists($typeclassname)) {
throw new InstallationException("class $typeclassname for type $type in plugin $pluginname was missing");
throw new InstallationException(get_string('pluginclassmissing', 'error', $typeclassname, $type, $pluginname));
}
}
}
......
This diff is collapsed.
......@@ -757,7 +757,16 @@ function safe_require($plugintype, $pluginname, $filename='lib.php', $function='
throw new Exception ('invalid require type');
}
$fullpath = get_config('docroot') . $plugintype . '/' . $pluginname . '/' . $filename;
if ($plugintype == 'blocktype') { // these are a bit of a special case
$bits = explode('/', $pluginname);
if (count($bits) == 2) {
$fullpath = get_config('docroot') . 'artefact/' . $bits[0] . '/blocktype/' . $bits[1] . '/' . $filename;
}
}
if (empty($fullpath)) {
$fullpath = get_config('docroot') . $plugintype . '/' . $pluginname . '/' . $filename;
}
if (!$realpath = realpath($fullpath)) {
if (!empty($nonfatal)) {
return false;
......@@ -786,7 +795,7 @@ function safe_require($plugintype, $pluginname, $filename='lib.php', $function='
function plugin_types() {
static $pluginstocheck;
if (empty($pluginstocheck)) {
$pluginstocheck = array('artefact', 'auth', 'notification', 'search');
$pluginstocheck = array('artefact', 'auth', 'notification', 'search', 'blocktype');
}
return $pluginstocheck;
}
......@@ -821,6 +830,10 @@ function generate_artefact_class_name($type) {
return 'ArtefactType' . ucfirst($type);
}
function generate_blocktype_class_name($type) {
return 'BlockType' . ucfirst($type);
}
/**
* Fires an event which can be handled by different parts of the system
*/
......
......@@ -380,6 +380,8 @@ function upgrade_plugin($upgrade) {
delete_records_select('artefact_installed_type', $select,
array_merge(array($pluginname),$types));
}
//@todo install blocks here too.
}
$prevversion = (empty($upgrade->install)) ? $upgrade->from : 0;
......@@ -500,117 +502,41 @@ function core_install_defaults() {
set_profile_field($user->id, 'firstname', $user->firstname);
set_profile_field($user->id, 'lastname', $user->lastname);
require('template.php');
$exceptions = upgrade_templates(true);
set_config('installed', true);
db_commit();
return $exceptions;
}
function upgrade_templates($continue=false) {
$exceptions = array();
$dbtemplates = array();
// check dataroot first, they get precedence.
$templates = get_dir_contents(get_config('dataroot') . 'templates/');
foreach ($templates as $dir) {
try {
$dbtemplates[$dir] = template_parse($dir);
}
catch (TemplateParserException $e) {
if (empty($continue)) {
throw $e;
function local_xmldb_contents_sub(&$contents) {
$searchstring = '<!-- PLUGIN_TYPE_SUBSTITUTION -->';
if (strstr($contents, $searchstring) === 0) {
return;
}
// ok, we're in the main file and we need to install all the plugin tables
// get the basic skeleton structure
$plugintables = file_get_contents(get_config('docroot') . 'lib/db/plugintables.xml');
$tosub = '';
foreach (plugin_types() as $plugin) {
// any that want their own stuff can put it in docroot/plugintype/lib/db/plugintables.xml - like auth is a bit special
$specialcase = get_config('docroot') . $plugin . '/plugintables.xml';
if (is_readable($specialcase)) {
$tosub .= file_get_contents($specialcase) . "\n";
}
else {
require_once(get_config('docroot') . $plugin . '/lib.php');
if (method_exists(generate_class_name($plugin), 'extra_xmldb_substitution')) {
$replaced = call_static_method(generate_class_name($plugin), 'extra_xmldb_substitution', $plugintables);
}
$exceptions[] = $e;
}
}
// and now system templates
$templates = get_dir_contents(get_config('libroot') . 'templates/');
foreach ($templates as $dir) {
if (array_key_exists($dir, $dbtemplates)) { // dataroot gets preference
continue;
}
try {
$dbtemplates[$dir] = template_parse($dir);
}
catch (TemplateParserException $e) {
if (empty($continue)) {
throw $e;
else {
$replaced = $plugintables;
}
$exceptions[] = $e;
}
}
foreach ($dbtemplates as $name => $data) {
try {
$ids = upgrade_template($name, $data);
}
catch (TemplateParserException $e) {
if (empty($continue)) {
throw $e;
$tosub .= str_replace('__PLUGINTYPE__', $plugin, $replaced) . "\n";
$extratables = get_config('docroot') . $plugin . '/extratables.xml';
if (is_readable($extratables)) {
$tosub .= file_get_contents($extratables) . "\n";
}
$exceptions[] = $e;
unset($dbtemplates[$name]);
continue;
}
}
if (count($dbtemplates) > 0) {
set_field_select('template', 'deleted', 1,
'name NOT IN (' . implode(',', db_array_to_ph(array_keys($dbtemplates))). ')',
array_keys($dbtemplates));
}
else {
set_field('template', 'deleted', 1);
}
return $exceptions;
}
/**
* This function upgrades or installs an individual template.
*
* @param $name the template name
* @param $data what you would get from template_parse
*/
function upgrade_template($name, $data) {
if (!is_readable($data['location'] . 'config.php')) {
$e = new TemplateParserException("missing config.php for template $name");
if (empty($continue)) {
throw $e;
}
$exceptions[] = $e;
continue;
}
require_once($data['location'] . 'config.php');
$fordb = new StdClass;
$fordb->name = $name;
$fordb->mtime = db_format_timestamp(time());
$fordb->title = $template->title;
$fordb->description = $template->description;
$fordb->category = $template->category;
$fordb->mtime = db_format_timestamp(time());
$fordb->cacheddata = serialize($data['parseddata']);
if (isset($data['thumbnail'])) {
$fordb->thumbnail = 1;
}
if (isset($template->owner)) {
$fordb->owner = $template->owner;
}
else {
$fordb->owner = 0; // root user
}
if (record_exists('template', 'name', $name)) {
update_record('template', $fordb, 'name');
}
else {
$fordb->ctime = $fordb->mtime;
insert_record('template', $fordb);
}
$contents = str_replace($searchstring, $tosub, $contents);
}
?>
......@@ -41,7 +41,6 @@ class View {
private $description;