/**
 * Provides a mechanism for choosing one or more artefacts from a list of them.
 *
 * @param Pieform  $form    The form to render the element for
 * @param array    $element The element to render
 * @return string           The HTML for the element
 */
function pieform_element_artefactchooser(Pieform $form, $element)
{
    global $USER, $pagination_js;
    $value = $form->get_value($element);
    $element['offset'] = param_integer('offset', 0);
    list($html, $pagination, $count) = View::build_artefactchooser_data($element, $form->get_property('viewgroup'), $form->get_property('viewinstitution'));
    $smarty = smarty_core();
    $smarty->assign('datatable', $element['name'] . '_data');
    $smarty->assign('artefacts', $html);
    $smarty->assign('pagination', $pagination['html']);
    $formname = $form->get_name();
    $smarty->assign('blockinstance', substr($formname, strpos($formname, '_') + 1));
    // Save the pagination javascript for later, when it is asked for. This is
    // messy, but can't be helped until Pieforms goes to a more OO way of
    // managing stuff.
    $pagination_js = $pagination['javascript'];
    $baseurl = View::make_base_url();
    $smarty->assign('browseurl', $baseurl);
    $smarty->assign('searchurl', $baseurl . '&s=1');
    $smarty->assign('searchable', !empty($element['search']));
    return $smarty->fetch('form/artefactchooser.tpl');
}
Example #2
0
 /**
  * Builds data for the artefact chooser.
  *
  * This builds three pieces of information:
  *
  * - HTML containing table rows
  * - Pagination HTML and Javascript
  * - The total number of artefacts found
  * - Artefact fields to return
  */
 public static function build_artefactchooser_data($data, $group = null, $institution = null)
 {
     global $USER;
     // If lazyload is set, immediately return an empty resultset
     // In the case of forms using lazyload, lazyload is set to false by subsequent requests via ajax,
     // for example in views/artefactchooser.json.php, at which time the full resultset is returned.
     if (isset($data['lazyload']) && $data['lazyload']) {
         $result = '';
         $pagination = build_pagination(array('id' => $data['name'] . '_pagination', 'class' => 'ac-pagination', 'url' => View::make_base_url() . (param_boolean('s') ? '&s=1' : ''), 'count' => 0, 'limit' => 0, 'offset' => 0, 'datatable' => $data['name'] . '_data', 'jsonscript' => 'view/artefactchooser.json.php', 'firsttext' => '', 'previoustext' => '', 'nexttext' => '', 'lasttext' => '', 'numbersincludefirstlast' => false, 'extradata' => array('value' => $data['defaultvalue'], 'blocktype' => $data['blocktype'], 'group' => $group, 'institution' => $institution)));
         return array($result, $pagination, 0, 0, array());
     }
     $search = '';
     if (!empty($data['search']) && param_boolean('s')) {
         $search = param_variable('search', '');
         // Maybe later, depending on performance - don't search if there's
         // not enough characters. Prompts should be added to the UI too.
         //if (strlen($search) < 3) {
         //    $search = '';
         //}
     }
     $data['search'] = $search;
     $data['offset'] -= $data['offset'] % $data['limit'];
     safe_require('blocktype', $data['blocktype']);
     $blocktypeclass = generate_class_name('blocktype', $data['blocktype']);
     $data['sortorder'] = array(array('fieldname' => 'title', 'order' => 'ASC'));
     if (method_exists($blocktypeclass, 'artefactchooser_get_sort_order')) {
         $data['sortorder'] = call_static_method($blocktypeclass, 'artefactchooser_get_sort_order');
     }
     list($artefacts, $totalartefacts) = self::get_artefactchooser_artefacts($data, $USER, $group, $institution);
     $selectone = $data['selectone'];
     $value = $data['defaultvalue'];
     $elementname = $data['name'];
     $template = $data['template'];
     $returnfields = isset($data['returnfields']) ? $data['returnfields'] : null;
     $returnartefacts = array();
     $result = '';
     if ($artefacts) {
         if (!empty($data['ownerinfo'])) {
             require_once get_config('docroot') . 'artefact/lib.php';
             $userid = $group || $institution ? null : $USER->get('id');
             foreach (artefact_get_owner_info(array_keys($artefacts)) as $k => $v) {
                 if ($artefacts[$k]->owner !== $userid || $artefacts[$k]->group !== $group || $artefacts[$k]->institution !== $institution) {
                     $artefacts[$k]->ownername = $v->name;
                     $artefacts[$k]->ownerurl = $v->url;
                 }
             }
         }
         foreach ($artefacts as &$artefact) {
             safe_require('artefact', get_field('artefact_installed_type', 'plugin', 'name', $artefact->artefacttype));
             if (method_exists($blocktypeclass, 'artefactchooser_get_element_data')) {
                 $artefact = call_static_method($blocktypeclass, 'artefactchooser_get_element_data', $artefact);
             }
             // Build the radio button or checkbox for the artefact
             $formcontrols = '';
             if ($selectone) {
                 $formcontrols .= '<input type="radio" class="radio" id="' . hsc($elementname . '_' . $artefact->id) . '" name="' . hsc($elementname) . '" value="' . hsc($artefact->id) . '"';
                 if ($value == $artefact->id) {
                     $formcontrols .= ' checked="checked"';
                 }
                 $formcontrols .= '>';
             } else {
                 $formcontrols .= '<input type="checkbox" id="' . hsc($elementname . '_' . $artefact->id) . '" name="' . hsc($elementname) . '[' . hsc($artefact->id) . ']"';
                 if ($value && in_array($artefact->id, $value)) {
                     $formcontrols .= ' checked="checked"';
                 }
                 $formcontrols .= ' class="artefactid-checkbox checkbox">';
                 $formcontrols .= '<input type="hidden" name="' . hsc($elementname) . '_onpage[]" value="' . hsc($artefact->id) . '" class="artefactid-onpage">';
             }
             $smarty = smarty_core();
             $smarty->assign('artefact', $artefact);
             $smarty->assign('elementname', $elementname);
             $smarty->assign('formcontrols', $formcontrols);
             $result .= $smarty->fetch($template) . "\n";
             if ($returnfields) {
                 $returnartefacts[$artefact->id] = array();
                 foreach ($returnfields as $f) {
                     if ($f == 'safedescription') {
                         $returnartefacts[$artefact->id]['safedescription'] = clean_html($artefact->description);
                         continue;
                     }
                     if ($f == 'attachments') {
                         // Check if the artefact has attachments - we need to update the instance config form
                         // to have those attachments selected.
                         $attachment_ids = get_column('artefact_attachment', 'attachment', 'artefact', $artefact->id);
                         $returnartefacts[$artefact->id]['attachments'] = $attachment_ids;
                         continue;
                     }
                     $returnartefacts[$artefact->id][$f] = $artefact->{$f};
                 }
             }
         }
         if ($returnfields && !empty($data['getblocks'])) {
             // Get ids of the blocks containing these artefacts
             $blocks = get_records_select_array('view_artefact', 'artefact IN (' . join(',', array_fill(0, count($artefacts), '?')) . ')', array_keys($artefacts));
             if (!empty($blocks)) {
                 // For each artefact, attach a list of block ids of all the blocks
                 // that contain it.
                 foreach ($blocks as $block) {
                     if (empty($returnartefacts[$block->artefact]['blocks'])) {
                         $returnartefacts[$block->artefact]['blocks'] = array();
                     }
                     $returnartefacts[$block->artefact]['blocks'][] = $block->block;
                 }
             }
         }
     }
     $pagination = build_pagination(array('id' => $elementname . '_pagination', 'class' => 'ac-pagination', 'url' => View::make_base_url() . (param_boolean('s') ? '&s=1' : ''), 'count' => $totalartefacts, 'limit' => $data['limit'], 'offset' => $data['offset'], 'datatable' => $elementname . '_data', 'jsonscript' => 'view/artefactchooser.json.php', 'firsttext' => '', 'previoustext' => '', 'nexttext' => '', 'lasttext' => '', 'numbersincludefirstlast' => false, 'extradata' => array('value' => $value, 'blocktype' => $data['blocktype'], 'group' => $group, 'institution' => $institution)));
     return array($result, $pagination, $totalartefacts, $data['offset'], $returnartefacts);
 }
Example #3
0
 /**
  * Builds the configuration pieform for this blockinstance
  *
  * @return array Array with two keys: 'html' for raw html, 'javascript' for
  *               javascript to run, 'css' for dynamic css to add to header
  */
 public function build_configure_form($new = false)
 {
     static $renderedform;
     if (!empty($renderedform)) {
         return $renderedform;
     }
     safe_require('blocktype', $this->get('blocktype'));
     $blocktypeclass = generate_class_name('blocktype', $this->get('blocktype'));
     $elements = call_static_method($blocktypeclass, 'instance_config_form', $this, $this->get_view()->get('template'));
     // Block types may specify a method to generate a default title for a block
     $hasdefault = method_exists($blocktypeclass, 'get_instance_title');
     $title = $this->get('title');
     $configdata = $this->get('configdata');
     $retractable = isset($configdata['retractable']) ? $configdata['retractable'] : false;
     $retractedonload = isset($configdata['retractedonload']) ? $configdata['retractedonload'] : $retractable;
     if (call_static_method($blocktypeclass, 'override_instance_title', $this)) {
         $titleelement = array('type' => 'hidden', 'value' => $title);
     } else {
         $titleelement = array('type' => 'text', 'title' => get_string('blocktitle', 'view'), 'description' => $hasdefault ? get_string('defaulttitledescription', 'blocktype.' . blocktype_name_to_namespaced($this->get('blocktype'))) : null, 'defaultvalue' => $title, 'rules' => array('maxlength' => 255), 'hidewhenempty' => $hasdefault, 'expandtext' => get_string('setblocktitle'));
     }
     $elements = array_merge(array('title' => $titleelement, 'blockconfig' => array('type' => 'hidden', 'value' => $this->get('id')), 'id' => array('type' => 'hidden', 'value' => $this->get('view')), 'change' => array('type' => 'hidden', 'value' => 1), 'new' => array('type' => 'hidden', 'value' => $new)), $elements, array('retractable' => array('type' => 'select', 'title' => get_string('retractable', 'view'), 'description' => get_string('retractabledescription', 'view'), 'options' => array(BlockInstance::RETRACTABLE_NO => get_string('no'), BlockInstance::RETRACTABLE_YES => get_string('yes'), BlockInstance::RETRACTABLE_RETRACTED => get_string('retractedonload', 'view')), 'defaultvalue' => $retractable + $retractedonload)));
     if ($new) {
         $cancel = get_string('remove');
         $elements['removeoncancel'] = array('type' => 'hidden', 'value' => 1);
         $elements['sure'] = array('type' => 'hidden', 'value' => 1);
     } else {
         $cancel = get_string('cancel');
     }
     // Add submit/cancel buttons
     $elements['action_configureblockinstance_id_' . $this->get('id')] = array('type' => 'submitcancel', 'class' => 'btn-default', 'value' => array(get_string('save'), $cancel), 'goto' => View::make_base_url());
     $configdirs = array(get_config('libroot') . 'form/');
     if ($this->get('artefactplugin')) {
         $configdirs[] = get_config('docroot') . 'artefact/' . $this->get('artefactplugin') . '/form/';
     }
     $form = array('name' => 'instconf', 'renderer' => 'div', 'validatecallback' => array(generate_class_name('blocktype', $this->get('blocktype')), 'instance_config_validate'), 'successcallback' => array($this, 'instance_config_store'), 'jsform' => true, 'jssuccesscallback' => 'blockConfigSuccess', 'jserrorcallback' => 'blockConfigError', 'elements' => $elements, 'viewgroup' => $this->get_view()->get('group'), 'group' => $this->get_view()->get('group'), 'viewinstitution' => $this->get_view()->get('institution'), 'institution' => $this->get_view()->get('institution'), 'configdirs' => $configdirs, 'plugintype' => 'blocktype', 'pluginname' => $this->get('blocktype'));
     if (param_variable('action_acsearch_id_' . $this->get('id'), false)) {
         $form['validate'] = false;
     }
     require_once 'pieforms/pieform.php';
     $pieform = new Pieform($form);
     if ($pieform->is_submitted()) {
         global $SESSION;
         $SESSION->add_error_msg(get_string('errorprocessingform'));
     }
     $html = $pieform->build();
     // We probably need a new version of $pieform->build() that separates out the js
     // Temporary evil hack:
     if (preg_match('/<script type="(text|application)\\/javascript">(new Pieform\\(.*\\);)<\\/script>/', $html, $matches)) {
         $js = "var pf_{$form['name']} = " . $matches[2] . "pf_{$form['name']}.init();";
     } else {
         $js = '';
     }
     // We need to load any javascript required for the pieform. We do this
     // by checking for an api function that has been added especially for
     // the purpose, but that is not part of Pieforms. Maybe one day later
     // it will be though
     foreach ($elements as $key => $element) {
         $element['name'] = $key;
         $function = 'pieform_element_' . $element['type'] . '_views_js';
         if (is_callable($function)) {
             $js .= call_user_func_array($function, array($pieform, $element));
         }
     }
     $configjs = call_static_method($blocktypeclass, 'get_instance_config_javascript', $this);
     if (is_array($configjs)) {
         $js .= $this->get_get_javascript_javascript($configjs);
     } else {
         if (is_string($configjs)) {
             $js .= $configjs;
         }
     }
     // We need to load any dynamic css required for the pieform. We do this
     // by checking for an api function that has been added especially for
     // the purpose, but that is not part of Pieforms. Maybe one day later
     // it will be though
     $css = array();
     foreach ($elements as $key => $element) {
         $element['name'] = $key;
         $function = 'pieform_element_' . $element['type'] . '_views_css';
         if (is_callable($function)) {
             $css[] = call_user_func_array($function, array($pieform, $element));
         }
     }
     $renderedform = array('html' => $html, 'javascript' => $js, 'css' => $css);
     return $renderedform;
 }
Example #4
0
 public static function blockconfig_filebrowser_element(&$instance, $default = array())
 {
     return array('name' => 'filebrowser', 'type' => 'filebrowser', 'title' => get_string('file', 'artefact.file'), 'folder' => (int) param_variable('folder', 0), 'highlight' => null, 'browse' => true, 'page' => View::make_base_url(), 'config' => array('upload' => true, 'uploadagreement' => get_config_plugin('artefact', 'file', 'uploadagreement'), 'createfolder' => false, 'edit' => false, 'select' => true, 'alwaysopen' => true, 'publishing' => true), 'tabs' => $instance->get_view()->ownership(), 'defaultvalue' => $default, 'selectlistcallback' => 'artefact_get_records_by_id');
 }
Example #5
0
 public static function blockconfig_filebrowser_element(&$instance, $default = array())
 {
     global $USER;
     $resizeonuploaduserdefault = $USER->get_account_preference('resizeonuploaduserdefault');
     return array('name' => 'filebrowser', 'type' => 'filebrowser', 'title' => get_string('file', 'artefact.file'), 'folder' => (int) param_variable('folder', 0), 'highlight' => null, 'browse' => true, 'page' => get_config('wwwroot') . 'view/blocks.php' . View::make_base_url(), 'config' => array('upload' => true, 'resizeonuploaduseroption' => get_config_plugin('artefact', 'file', 'resizeonuploaduseroption'), 'resizeonuploaduserdefault' => $resizeonuploaduserdefault, 'uploadagreement' => get_config_plugin('artefact', 'file', 'uploadagreement'), 'createfolder' => false, 'edit' => false, 'tag' => true, 'select' => true, 'alwaysopen' => true, 'publishing' => true), 'tabs' => $instance->get_view()->ownership(), 'defaultvalue' => $default, 'selectlistcallback' => 'artefact_get_records_by_id');
 }
 /**
  * Builds data for the artefact chooser.
  *
  * This builds three pieces of information:
  *
  * - HTML containing table rows
  * - Pagination HTML and Javascript
  * - The total number of artefacts found
  */
 public static function build_artefactchooser_data($data, $group = null, $institution = null)
 {
     global $USER;
     $search = '';
     if (!empty($data['search']) && param_boolean('s')) {
         $search = param_variable('search', '');
         // Maybe later, depending on performance - don't search if there's
         // not enough characters. Prompts should be added to the UI too.
         //if (strlen($search) < 3) {
         //    $search = '';
         //}
     }
     $data['search'] = $search;
     $data['offset'] -= $data['offset'] % $data['limit'];
     safe_require('blocktype', $data['blocktype']);
     $blocktypeclass = generate_class_name('blocktype', $data['blocktype']);
     $data['sortorder'] = array(array('fieldname' => 'title', 'order' => 'ASC'));
     if (method_exists($blocktypeclass, 'artefactchooser_get_sort_order')) {
         $data['sortorder'] = call_static_method($blocktypeclass, 'artefactchooser_get_sort_order');
     }
     list($artefacts, $totalartefacts) = self::get_artefactchooser_artefacts($data, $USER, $group, $institution);
     $selectone = $data['selectone'];
     $value = $data['defaultvalue'];
     $elementname = $data['name'];
     $template = $data['template'];
     $result = '';
     if ($artefacts) {
         foreach ($artefacts as &$artefact) {
             safe_require('artefact', get_field('artefact_installed_type', 'plugin', 'name', $artefact->artefacttype));
             if (method_exists($blocktypeclass, 'artefactchooser_get_element_data')) {
                 $artefact = call_static_method($blocktypeclass, 'artefactchooser_get_element_data', $artefact);
             }
             // Build the radio button or checkbox for the artefact
             $formcontrols = '';
             if ($selectone) {
                 $formcontrols .= '<input type="radio" class="radio" id="' . hsc($elementname . '_' . $artefact->id) . '" name="' . hsc($elementname) . '" value="' . hsc($artefact->id) . '"';
                 if ($value == $artefact->id) {
                     $formcontrols .= ' checked="checked"';
                 }
                 $formcontrols .= '>';
             } else {
                 $formcontrols .= '<input type="checkbox" id="' . hsc($elementname . '_' . $artefact->id) . '" name="' . hsc($elementname) . '[' . hsc($artefact->id) . ']"';
                 if ($value && in_array($artefact->id, $value)) {
                     $formcontrols .= ' checked="checked"';
                 }
                 $formcontrols .= ' class="artefactid-checkbox checkbox">';
                 $formcontrols .= '<input type="hidden" name="' . hsc($elementname) . '_onpage[]" value="' . hsc($artefact->id) . '" class="artefactid-onpage">';
             }
             $smarty = smarty_core();
             $smarty->assign('artefact', $artefact);
             $smarty->assign('elementname', $elementname);
             $smarty->assign('formcontrols', $formcontrols);
             $result .= $smarty->fetch($template) . "\n";
         }
     }
     $pagination = build_pagination(array('id' => $elementname . '_pagination', 'class' => 'ac-pagination', 'url' => View::make_base_url() . (param_boolean('s') ? '&s=1' : ''), 'count' => $totalartefacts, 'limit' => $data['limit'], 'offset' => $data['offset'], 'datatable' => $elementname . '_data', 'jsonscript' => 'view/artefactchooser.json.php', 'firsttext' => '', 'previoustext' => '', 'nexttext' => '', 'lasttext' => '', 'numbersincludefirstlast' => false, 'extradata' => array('value' => $value, 'blocktype' => $data['blocktype'], 'group' => $group, 'institution' => $institution)));
     return array($result, $pagination, $totalartefacts, $data['offset']);
 }
Example #7
0
 /**
  * Builds the configuration pieform for the image browser
  *
  * @return array Array with two keys: 'html' for raw html, 'javascript' for
  *               javascript to run
  */
 public function build_image_browser_form()
 {
     require_once 'view.php';
     static $renderedform;
     if (!empty($renderedform)) {
         return $renderedform;
     }
     safe_require('artefact', 'file');
     $this->set('artefactplugin', 'file');
     $elements['url'] = array('type' => 'text', 'title' => get_string('url'), 'size' => 50);
     $elements['artefactfieldset'] = array('type' => 'fieldset', 'collapsible' => true, 'collapsed' => true, 'legend' => get_string('image'), 'class' => 'last select-file mtl', 'elements' => array('artefactid' => self::config_filebrowser_element($this, null)));
     $configdata = $this->get('configdata');
     $elements['sure'] = array('type' => 'hidden', 'value' => 1);
     // use these to determine which space to display to upload files to
     $elements['post'] = array('type' => 'hidden', 'value' => $this->post);
     $elements['group'] = array('type' => 'hidden', 'value' => $this->group);
     $elements['institution'] = array('type' => 'hidden', 'value' => $this->institution);
     $elements['view'] = array('type' => 'hidden', 'value' => $this->view);
     // tinymce specific elements
     $alignoptions = array('none' => '--', 'top' => 'Top', 'middle' => 'Middle', 'bottom' => 'Bottom', 'left' => 'Left', 'right' => 'Right');
     $elements['toggleformatting'] = array('type' => 'html', 'class' => 'toggleablecontainer', 'value' => '<div id="formattingoptionstoggle" class="retracted arrow"><label>Image formatting options</label></div>');
     $elements['formattingoptions'] = array('type' => 'container', 'name' => 'formattingoptions', 'class' => 'js-hidden', 'elements' => array('width' => array('type' => 'text', 'title' => get_string('dimensions'), 'size' => 3, 'rules' => array('maxlength' => 4)), 'height' => array('type' => 'text', 'size' => 3, 'rules' => array('maxlength' => 4)), 'constrain' => array('type' => 'switchbox', 'title' => get_string('constrain'), 'defaultvalue' => true), 'vspace' => array('type' => 'text', 'title' => get_string('vspace'), 'size' => 3, 'rules' => array('maxlength' => 2)), 'hspace' => array('type' => 'text', 'title' => get_string('hspace'), 'size' => 3, 'rules' => array('maxlength' => 2)), 'border' => array('type' => 'text', 'title' => get_string('border'), 'size' => 3, 'rules' => array('maxlength' => 2)), 'align' => array('defaultvalue' => 'none', 'type' => 'select', 'title' => get_string('alignment'), 'options' => $alignoptions), 'style' => array('type' => 'text', 'title' => get_string('style'), 'size' => 50)));
     $wwwroot = get_config('wwwroot');
     $goto = "";
     if ($this->view) {
         $goto = $wwwroot . 'view/blocks.php' . View::make_base_url();
         // editing forum topic
     } else {
         if ($this->post) {
             $goto = $wwwroot . "interaction/forum/edittopic.php?id=" . $this->post;
         } else {
             if ($this->group) {
                 // editing forum itself
                 $goto = $wwwroot . "interaction/edit.php?id=" . $this->group;
             }
         }
     }
     // Add submit/cancel buttons
     // goto should not be used by those with javascript - cancel is handled by js function which simply removes the image browser
     $elements['action_submitimage'] = array('type' => 'submitcancel', 'class' => 'btn-default', 'value' => array(get_string('submit'), get_string('cancel')), 'goto' => $goto);
     $configdirs = array(get_config('libroot') . 'form/');
     if ($this->get('artefactplugin')) {
         $configdirs[] = get_config('docroot') . 'artefact/' . $this->get('artefactplugin') . '/form/';
     }
     $form = array('name' => 'imgbrowserconf', 'action' => get_config('wwwroot') . 'json/imagebrowser.json.php', 'renderer' => 'div', 'validatecallback' => array($this, 'config_validate'), 'successcallback' => array($this, 'config_success'), 'jsform' => true, 'jssuccesscallback' => 'imageBrowserConfigSuccess', 'jserrorcallback' => 'imageBrowserConfigError', 'elements' => $elements, 'viewgroup' => $this->get_view()->get('group'), 'group' => $this->get('group'), 'viewinstitution' => $this->get_view()->get('institution'), 'institution' => $this->get('institution'), 'configdirs' => $configdirs, 'plugintype' => 'blocktype', 'pluginname' => $this->get('blocktype'));
     require_once 'pieforms/pieform.php';
     $pieform = new Pieform($form);
     if ($pieform->is_submitted()) {
         global $SESSION;
         $SESSION->add_error_msg(get_string('errorprocessingform'));
     }
     $html = $pieform->build();
     // We probably need a new version of $pieform->build() that separates out the js
     // Temporary evil hack:
     if (preg_match('/<script type="(text|application)\\/javascript">(new Pieform\\(.*\\);)<\\/script>/', $html, $matches)) {
         $js = "var pf_{$form['name']} = " . $matches[2] . "pf_{$form['name']}.init();";
     } else {
         $js = '';
     }
     // We need to load any javascript required for the pieform. We do this
     // by checking for an api function that has been added especially for
     // the purpose, but that is not part of Pieforms. Maybe one day later
     // it will be though
     // $js = '';
     foreach ($elements as $key => $element) {
         $element['name'] = $key;
         $function = 'pieform_element_' . $element['type'] . '_views_js';
         if (is_callable($function)) {
             $js .= call_user_func_array($function, array($pieform, $element));
         }
     }
     $renderedform = array('html' => $html, 'javascript' => $js);
     return $renderedform;
 }
 /**
  * Builds the configuration pieform for this blockinstance
  *
  * @return array Array with two keys: 'html' for raw html, 'javascript' for
  *               javascript to run
  */
 public function build_configure_form($new = false)
 {
     static $renderedform;
     if (!empty($renderedform)) {
         return $renderedform;
     }
     safe_require('blocktype', $this->get('blocktype'));
     $elements = call_static_method(generate_class_name('blocktype', $this->get('blocktype')), 'instance_config_form', $this, $this->get_view()->get('template'));
     $blocktypeclass = generate_class_name('blocktype', $this->get('blocktype'));
     if ($this->get('title') != call_static_method($blocktypeclass, 'get_title')) {
         // If the title for this block has been set to something other than
         // the block title, use it unconditionally
         $title = $this->get('title');
     } else {
         if (method_exists($blocktypeclass, 'get_instance_title')) {
             // Block types can specify a default title for a block
             $title = call_static_method($blocktypeclass, 'get_instance_title', $this);
         } else {
             // A block that doesn't have a method for setting an instance
             // title, and hasn't had its title changed (e.g. a new textbox)
             $title = $this->get('title');
         }
     }
     $elements = array_merge(array('title' => array('type' => 'text', 'title' => get_string('blocktitle', 'view'), 'description' => method_exists($blocktypeclass, 'get_instance_title') ? get_string('defaulttitledescription', 'blocktype.' . blocktype_name_to_namespaced($this->get('blocktype'))) : null, 'defaultvalue' => $title), 'blockconfig' => array('type' => 'hidden', 'value' => $this->get('id')), 'id' => array('type' => 'hidden', 'value' => $this->get('view')), 'change' => array('type' => 'hidden', 'value' => 1), 'new' => array('type' => 'hidden', 'value' => $new)), $elements);
     if ($new) {
         $cancel = get_string('remove');
         $elements['removeoncancel'] = array('type' => 'hidden', 'value' => 1);
         $elements['sure'] = array('type' => 'hidden', 'value' => 1);
     } else {
         $cancel = get_string('cancel');
     }
     // Add submit/cancel buttons
     $elements['action_configureblockinstance_id_' . $this->get('id')] = array('type' => 'submitcancel', 'value' => array(get_string('save'), $cancel), 'goto' => View::make_base_url());
     $configdirs = array(get_config('libroot') . 'form/');
     if ($this->get('artefactplugin')) {
         $configdirs[] = get_config('docroot') . 'artefact/' . $this->get('artefactplugin') . '/form/';
     }
     $form = array('name' => 'instconf', 'renderer' => 'maharatable', 'validatecallback' => array(generate_class_name('blocktype', $this->get('blocktype')), 'instance_config_validate'), 'successcallback' => array($this, 'instance_config_store'), 'jsform' => true, 'jssuccesscallback' => 'blockConfigSuccess', 'jserrorcallback' => 'blockConfigError', 'elements' => $elements, 'viewgroup' => $this->get_view()->get('group'), 'group' => $this->get_view()->get('group'), 'viewinstitution' => $this->get_view()->get('institution'), 'institution' => $this->get_view()->get('institution'), 'configdirs' => $configdirs, 'plugintype' => 'blocktype', 'pluginname' => $this->get('blocktype'));
     if (param_variable('action_acsearch_id_' . $this->get('id'), false)) {
         $form['validate'] = false;
     }
     require_once 'pieforms/pieform.php';
     $pieform = new Pieform($form);
     if ($pieform->is_submitted()) {
         global $SESSION;
         $SESSION->add_error_msg(get_string('errorprocessingform'));
     }
     $html = $pieform->build();
     // We probably need a new version of $pieform->build() that separates out the js
     // Temporary evil hack:
     if (preg_match('/<script type="text\\/javascript">(new Pieform\\(.*\\);)<\\/script>/', $html, $matches)) {
         $js = "var pf_{$form['name']} = " . $matches[1] . "pf_{$form['name']}.init();";
     } else {
         $js = '';
     }
     // We need to load any javascript required for the pieform. We do this
     // by checking for an api function that has been added especially for
     // the purpose, but that is not part of Pieforms. Maybe one day later
     // it will be though
     // $js = '';
     foreach ($elements as $key => $element) {
         $element['name'] = $key;
         $function = 'pieform_element_' . $element['type'] . '_views_js';
         if (is_callable($function)) {
             $js .= call_user_func_array($function, array($pieform, $element));
         }
     }
     $renderedform = array('html' => $html, 'javascript' => $js);
     return $renderedform;
 }