/** * Copy simple unit * * This function copies a unit (NOT its children) into the current content tree * <br/>Example: * <code> * $currentContent = new EfrontContentTree(5); //Initialize content for lesson with id 5 * $sourceUnit = new EfrontUnit(20); //Get the unit with id = 20 * $currentContent -> copySimpleUnit($sourceUnit, false); //Copy the source unit into the content tree (at its end) * </code> * * @param EfrontUnit $sourceUnit The unit object to be copied * @param mixed $targetUnit The id of the parent unit (or the parent EfrontUnit)in which the new unit will be copied, or false (the unit will be appended at the end) * @param mixed $previousUnit The id of the previous unit (or the unit itself) of the new unit, or false (the unit will be put to the end of the units) * @param boolean $copyFiles whether to copy files as well. * @param boolean $copyQuestions Whether to copy questions as well * @return EfrontUnit The newly created unit object * @since 3.5.0 * @access public */ public function copySimpleUnit($sourceUnit, $targetUnit = false, $previousUnit = false, $copyFiles = true, $copyQuestions = true) { if (!$sourceUnit instanceof EfrontUnit) { $sourceUnit = new EfrontUnit($sourceUnit); } $newUnit['name'] = $sourceUnit->offsetGet('name'); $newUnit['ctg_type'] = $sourceUnit->offsetGet('ctg_type'); $newUnit['data'] = $sourceUnit->offsetGet('data'); $options = $sourceUnit->offsetGet('options'); $newOptions['complete_unit_setting'] = $options['complete_unit_setting']; $newOptions['hide_navigation'] = $options['hide_navigation']; $newOptions['maximize_viewport'] = $options['maximize_viewport']; $newOptions['object_ids'] = $options['object_ids']; $newUnit['options'] = serialize($newOptions); $newUnit['lessons_ID'] = $this->lessonId; if ($targetUnit) { if ($targetUnit instanceof EfrontUnit) { $newUnit['parent_content_ID'] = $targetUnit->offsetGet('id'); } else { if (eF_checkParameter($targetUnit, 'id')) { $newUnit['parent_content_ID'] = $targetUnit; } } if ($previousUnit instanceof EfrontUnit) { $newUnit['previous_content_ID'] = $previousUnit->offsetGet('id'); } else { if (eF_checkParameter($previousUnit, 'id')) { $newUnit['previous_content_ID'] = $previousUnit; } } $unit = $this->insertNode($newUnit); } else { $unit = $this->appendUnit($newUnit); } if ($copyFiles) { $files = $unit->getFiles(); $lesson = new EfrontLesson($this->lessonId); $data = $unit->offsetGet('data'); foreach ($files as $file) { try { $sourceFile = new EfrontFile($file); $sourceFileOffset = preg_replace("#" . G_LESSONSPATH . "#", "", $sourceFile['directory']); $position = strpos($sourceFileOffset, "/"); //check case that the file is in a subfolder of the lesson if ($position !== false) { $sourceLink = mb_substr($sourceFileOffset, $position + 1); mkdir($lesson->getDirectory() . $sourceLink . '/', 0755, true); $destinationPath = $lesson->getDirectory() . $sourceLink . '/' . basename($sourceFile['path']); $copiedFile = $sourceFile->copy($destinationPath, false); } else { $destinationPath = $lesson->getDirectory() . basename($sourceFile['path']); $copiedFile = $sourceFile->copy($destinationPath, false); } //@todo view_file.php?action=download&file=10410 //$data = str_replace("view_file.php?file=".$file, "view_file.php?file=".$copiedFile -> offsetGet('id'), $data); //$data = str_replace("&file=".$file, "&file=".$copiedFile -> offsetGet('id'), $data); //$data = str_replace("&file=".$file, "&file=".$copiedFile -> offsetGet('id'), $data); $data = preg_replace('#view_file\\.php(.*)file=' . $file . '#', 'view_file.php${1}file=' . $copiedFile->offsetGet('id'), $data); $folderId = $lesson->lesson['share_folder'] ? $lesson->lesson['share_folder'] : $lesson->lesson['id']; $data = preg_replace("#(" . G_SERVERNAME . ")*content/lessons/" . $sourceUnit['lessons_ID'] . "/(.*)#", "content/lessons/" . $folderId . '/${2}', $data); } catch (EfrontFileException $e) { if ($e->getCode() == EfrontFileException::FILE_ALREADY_EXISTS) { $copiedFile = new EfrontFile($destinationPath); //$data = str_replace("view_file.php?file=".$file, "view_file.php?file=".$copiedFile -> offsetGet('id'), $data); //$data = str_replace("&file=".$file, "&file=".$copiedFile -> offsetGet('id'), $data); //$data = str_replace("&file=".$file, "&file=".$copiedFile -> offsetGet('id'), $data); $data = preg_replace('#view_file\\.php(.*)file=' . $file . '#', 'view_file.php${1}file=' . $copiedFile->offsetGet('id'), $data); $folderId = $lesson->lesson['share_folder'] ? $lesson->lesson['share_folder'] : $lesson->lesson['id']; $data = preg_replace("#(" . G_SERVERNAME . ")*content/lessons/" . $sourceUnit['lessons_ID'] . "/(.*)#", "content/lessons/" . $folderId . '/${2}', $data, -1, $count); } } //this means that the file already exists } $unit->offsetSet('data', $data); if ($file && $unit['ctg_type'] == 'scorm' || $unit['ctg_type'] == 'scorm_test') { $d = new EfrontDirectory(dirname($file)); $d->copy($lesson->getDirectory() . basename(dirname($file)), true); } } $unit->persist(); // copying questions that belong to this unit if ($copyQuestions) { $questions = eF_getTableData("questions", "*", "content_ID=" . $sourceUnit->offsetGet('id')); if ($copyFiles) { $folderId = $lesson->lesson['share_folder'] ? $lesson->lesson['share_folder'] : $lesson->lesson['id']; } for ($k = 0; $k < sizeof($questions); $k++) { if ($copyFiles) { $questions[$k]['text'] = replaceQuestionPaths($questions[$k]['text'], $questions[$k]['lessons_ID'], $folderId); $questions[$k]['explanation'] = replaceQuestionPaths($questions[$k]['explanation'], $questions[$k]['lessons_ID'], $folderId); } $questions[$k]['content_ID'] = $unit->offsetGet('id'); $questions[$k]['lessons_ID'] = $unit->offsetGet('lessons_ID'); unset($questions[$k]['id']); eF_insertTableData("questions", $questions[$k]); } } return $unit; }
/** * Restore system * * This function is used to restore a backup previously taken * <br/>Example: * <code> * </code> * * @param EfrontFile $restoreFile The file restore from * @param boolean $force Force restore even if versions are incompatible * @since 3.5.2 * @access public */ public static function restore($restoreFile, $force = false) { if (!$restoreFile instanceof EfrontFile) { $restoreFile = new EfrontFile($restoreFile); } $tempDir = G_BACKUPPATH . 'temp/'; if (is_dir($tempDir)) { $dir = new EfrontDirectory($tempDir); $dir->delete(); } mkdir($tempDir, 0755); $restoreFile = $restoreFile->copy($tempDir . '/'); $restoreFile->uncompress(false); $filesystem = new FileSystemTree($tempDir); $iterator = new EfrontFileOnlyFilterIterator(new RecursiveIteratorIterator($filesystem->tree, RecursiveIteratorIterator::SELF_FIRST)); foreach ($iterator as $key => $value) { if (strpos($key, 'version.txt') !== false) { $backupVersion = file_get_contents($key); } } if (version_compare($backupVersion, G_VERSION_NUM) != 0 && !$force) { throw new Exception(_INCOMPATIBLEVERSIONS . '<br/> ' . _BACKUPVERSION . ':' . $backupVersion . ' / ' . _CURRENTVERSION . ': ' . G_VERSION_NUM, EfrontSystemException::INCOMPATIBLE_VERSIONS); } $sql = file_get_contents($tempDir . 'db_backup/sql.txt'); $sql = explode(";\n", $sql); $node = $filesystem->seekNode($tempDir . 'db_backup'); for ($i = 0; $i < sizeof($sql); $i += 2) { preg_match("/drop table (.+)/", $sql[$i], $matches); if ($matches[1]) { $temp[$matches[1]] = array($sql[$i], $sql[$i + 1]); } } $sql = $temp; //For each one of the tables that have backup data, recreate its table and import data $iterator = new EfrontFileOnlyFilterIterator(new RecursiveIteratorIterator(new RecursiveArrayIterator($node), RecursiveIteratorIterator::SELF_FIRST)); $GLOBALS['db']->Execute("SET FOREIGN_KEY_CHECKS=0"); foreach ($iterator as $file => $value) { $tableName = preg_replace("/\\.\\d+/", "", basename($file)); if (isset($sql[$tableName])) { try { eF_executeNew($sql[$tableName][0]); } catch (Exception $e) { /*Don't halt for missing tables that can't be deleted*/ } eF_executeNew($sql[$tableName][1]); unset($sql[$tableName]); } if (strpos($file, 'sql.txt') === false && strpos($file, 'version.txt') === false) { $data = unserialize(file_get_contents($file)); $tableExists = false; try { $tableExists = eF_describeTable($tableName); } catch (Exception $e) { } if ($tableExists !== false && !preg_match("/^\\w+_view\$/", $tableName)) { eF_insertTableDataMultiple($tableName, $data); } } } $GLOBALS['db']->Execute("SET FOREIGN_KEY_CHECKS=1"); //Turn off foreign key checks in order to be able to run "drop table" queries eF_executeNew("SET FOREIGN_KEY_CHECKS = 0;"); //For each one of the tables that don't have backup data, simply recreate foreach ($sql as $tableName => $query) { try { eF_executeNew($query[0]); } catch (Exception $e) { /*Don't halt for missing tables that can't be deleted*/ } eF_executeNew($query[1]); } eF_executeNew("SET FOREIGN_KEY_CHECKS = 1;"); if (is_dir(G_BACKUPPATH . 'temp/upload')) { $dir = new EfrontDirectory(G_BACKUPPATH . 'temp/upload'); $dir->copy(G_ROOTPATH . 'upload', true); } if (is_dir(G_BACKUPPATH . 'temp/lessons')) { $dir = new EfrontDirectory(G_BACKUPPATH . 'temp/lessons'); $dir->copy(G_CONTENTPATH . 'lessons', true); } if (is_dir(G_BACKUPPATH . 'temp/efront_root')) { $dir = new EfrontDirectory(G_BACKUPPATH . 'temp/efront_root'); $dir->copy(G_ROOTPATH, true); } if (is_dir(G_BACKUPPATH . 'temp/certificate_templates')) { $dir = new EfrontDirectory(G_BACKUPPATH . 'temp/certificate_templates'); $dir->copy(G_ROOTPATH . 'www/certificate_templates', true); } if (is_dir(G_BACKUPPATH . 'temp/editor_templates')) { $dir = new EfrontDirectory(G_BACKUPPATH . 'temp/editor_templates'); $dir->copy(G_ROOTPATH . 'www/content/editor_templates', true); } $dir = new EfrontDirectory($tempDir); $dir->delete(); if (function_exists('apc_clear_cache')) { apc_clear_cache('user'); } return true; }
/** * The main functionality * * (non-PHPdoc) * @see libraries/EfrontModule#getModule() */ public function getModule() { $smarty = $this->getSmartyVar(); $smarty->assign("T_MODULE_BASEDIR", $this->moduleBaseDir); $smarty->assign("T_MODULE_BASELINK", $this->moduleBaseLink); $smarty->assign("T_MODULE_BASEURL", $this->moduleBaseUrl); $form = new HTML_QuickForm("bootstrap_form", "post", $this->moduleBaseUrl, "", null, true); $form->registerRule('checkParameter', 'callback', 'eF_checkParameter'); $form->addElement('text', 'name', _NAME, 'class = "inputText"'); $form->addElement('static', '', _MODULE_BOOTSTRAP_WITHOUTTHECLASS, 'class = "inputText"'); $form->addRule('name', _THEFIELD . ' ' . _NAME . ' ' . _ISMANDATORY, 'required', null, 'client'); $form->addRule('name', _INVALIDFIELDDATA, 'checkParameter', 'alnum'); $form->addElement('text', 'title', _TITLE, 'class = "inputText"'); $form->addElement('text', 'creator', _MODULE_BOOTSTRAP_CREATOR, 'class = "inputText"'); $form->addElement('checkbox', 'administrator', _ADMINISTRATOR); $form->addElement('checkbox', 'professor', _PROFESSOR); $form->addElement('checkbox', 'student', _STUDENT); $form->addElement('checkbox', 'supervisor', _MODULE_BOOTSTRAP_SUPERVISORONLY); $form->addElement('checkbox', 'tabber', _MODULE_BOOTSTRAP_TABBER); $form->addElement('textarea', 'form', _MODULE_BOOTSTRAP_FORMFIELDS, 'class = "inputTextarea" style = "height:40px"'); $form->addElement('static', '', _MODULE_BOOTSTRAP_FORMINSTRUCTIONS); $form->addElement('textarea', 'grid', _MODULE_BOOTSTRAP_GRIDFIELDS, 'class = "inputTextarea" style = "height:40px"'); $form->addElement('static', '', _MODULE_BOOTSTRAP_GRIDINSTRUCTIONS); $form->addElement('checkbox', 'filemanager', _MODULE_BOOTSTRAP_FILEMANAGER); $form->addElement('textarea', 'description', _DESCRIPTION, 'class = "inputTextarea" style = "height:80px"'); //$form -> addElement('placing', 'student', _MODULE_BOOTSTRAP_NAME); $form->addElement('checkbox', 'overwrite', _MODULE_BOOTSTRAP_OVERWRITEIFEXISTS); $form->addElement('submit', 'submit', _INSTALL, 'class = "flatButton"'); $form->setDefaults(array('creator' => $this->getCurrentUser()->user['name'] . ' ' . $this->getCurrentUser()->user['surname'])); if ($form->isSubmitted() && $form->validate()) { try { $values = $form->exportValues(); if (!$values['administrator'] && !$values['student'] && !$values['professor']) { throw new Exception(_MODULE_BOOTSTRAP_YOUMUSTSELECTATLEASTATYPE); } $module_name = $values['name']; $module_dir = $this->moduleBaseDir . 'module_' . $module_name; if (!is_dir($module_dir)) { mkdir($module_dir, 0755); } if (!is_dir("{$module_dir}/img")) { mkdir("{$module_dir}/img", 0755); } if (!is_dir("{$module_dir}/assets")) { mkdir("{$module_dir}/assets", 0755); } if ($values['administrator']) { $roles[] = 'administrator'; } if ($values['professor']) { $roles[] = 'professor'; } if ($values['student']) { $roles[] = 'student'; } $roles = '"' . implode('","', $roles) . '"'; $contents = $tabber = $block = $grid_content = $fields_content = ''; $fields = array(); if ($values['form']) { foreach (explode(",", $values['form']) as $property) { $property = explode(":", $property); array_walk($property, create_function('&$v', '$v = trim($v);')); $fields[] = array('type' => $property[0], 'name' => $property[1], 'title' => $property[2], 'extra' => $property[3]); } foreach ($fields as $value) { $fields_content .= '$form -> addElement("' . $value["type"] . '", "' . $value["name"] . '", "' . $value["title"] . '", "' . $value["extra"] . '");'; } } else { $fields = "return false;"; } if ($values['filemanager']) { $file_manager = "true"; } else { $file_manager = "false"; } if ($values['grid']) { $headers = $rows = $grid_contents = array(); $grid_content = "\$data = array(array("; foreach (explode(",", $values['grid']) as $property) { $property = trim($property); if ($property) { $property = explode(":", $property); array_walk($property, create_function('&$v', '$v = trim($v);')); $headers[] = "\r\n\t\t\t\t\t\t\t\t<td class = 'topTitle' name = '{$property[0]}'>{$property[1]}</td>"; $rows[] = "\r\n\t\t\t\t\t\t\t\t<td>{\$item.{$property[0]}}</td>"; $grid_content .= "'{$property[0]}' => 'sample value',"; } } $grid_content .= "));"; $headers = implode("\n", $headers); $rows = implode("\n", $rows); $contents .= <<<GRID {capture name = "t_grid_code"} <!--ajax:{$module_name}Table--> \t\t\t\t\t<table style = "width:100%" class = "sortedTable" size = "{\$T_TABLE_SIZE}" sortBy = "0" id = "{$module_name}Table" useAjax = "1" rowsPerPage = "{\$smarty.const.G_DEFAULT_TABLE_SIZE}" url = "{\$T_MODULE_BASEURL}&"> \t\t\t\t\t\t<tr class = "topTitle"> \t\t\t\t\t\t\t{$headers} \t\t\t\t\t\t</tr> \t{foreach name = 'demo_data_list' key = 'key' item = 'item' from = \$T_DATA_SOURCE} \t\t\t\t\t\t<tr class = "defaultRowHeight {cycle values = "oddRowColor, evenRowColor"}"> \t\t\t\t\t\t\t{$rows} \t\t\t\t\t\t</tr> \t{foreachelse} \t\t\t\t\t<tr class = "defaultRowHeight oddRowColor"><td class = "emptyCategory" colspan = "100%">{\$smarty.const._NODATAFOUND}</td></tr> \t{/foreach} \t\t\t\t</table> <!--/ajax:{$module_name}Table--> {/capture} GRID; if ($values['tabber']) { $tabber = "tabber = \"{$module_name}_grid\""; } $block .= '{eF_template_printBlock ' . $tabber . ' title = "' . _MODULE_BOOTSTRAP_DATA . '" data = $smarty.capture.t_grid_code}' . "\n"; } if ($values['form']) { $contents .= <<<FORM {capture name = "t_form_block_code"} \t{eF_template_printForm form = \$T_FORM} {/capture} FORM; if ($values['tabber']) { $tabber = "tabber = \"{$module_name}_form\""; } $block .= '{eF_template_printBlock ' . $tabber . ' title = "' . _MODULE_BOOTSTRAP_FORM . '" data = $smarty.capture.t_form_block_code}' . "\n"; } if ($values['filemanager']) { $contents .= <<<FILEMANAGER {capture name = "t_block_code"} \t{\$T_FILE_MANAGER} {/capture} FILEMANAGER; if ($values['tabber']) { $tabber = "tabber = \"{$module_name}_filemanager\""; } $block .= '{eF_template_printBlock ' . $tabber . ' title = "' . _MODULE_BOOTSTRAP_FILES . '" data = $smarty.capture.t_block_code}'; } if ($values['empty_page']) { $contents .= <<<EMPTY {capture name = "t_block_code"} \tCode here {/capture} EMPTY; if ($values['tabber']) { $tabber = "tabber = \"{$module_name}_page\""; } $block .= '{eF_template_printBlock ' . $tabber . ' title = "' . _MODULE_BOOTSTRAP_PAGE . '" data = $smarty.capture.t_block_code}'; } if ($values['tabber']) { $contents = <<<CONTENTS {$contents} {capture name = "t_code"} <div class = "tabber"> {$block} </div> {/capture} {eF_template_printBlock title = "{$values["title"]}" data = \$smarty.capture.t_code} CONTENTS; } else { $contents = $contents . $block; } file_put_contents("{$module_dir}/module.tpl", $contents); $search = array("###NAME###", "###TITLE###", "###ROLES###", "###FIELDS###", "###FILE_MANAGER###", "###GRID_DATA###"); $replace = array($module_name, $values['title'], $roles, $fields_content, $file_manager, $grid_content); $contents = file_get_contents($this->moduleBaseDir . "template/module_.class.php"); $contents = str_replace($search, $replace, $contents); file_put_contents("{$module_dir}/module_{$module_name}.class.php", $contents); $date = date("Y m d"); $xml = <<<XML <?xml version="1.0" ?> <module> \t<title>{$values['title']}</title> \t<author>{$values['creator']}</author> \t<date>{$date}</date> \t<version>1.0</version> \t<description>{$values['description']}</description> \t<className>module_{$module_name}</className> \t<requires>3.6.11</requires> </module> XML; file_put_contents("{$module_dir}/module.xml", $xml); copy($this->moduleBaseDir . "img/logo.png", "{$module_dir}/img/logo.png"); copy($this->moduleBaseDir . "img/generic.png", "{$module_dir}/img/generic.png"); $directory = new EfrontDirectory($module_dir); if (is_dir(G_MODULESPATH . basename($module_dir))) { if ($values['overwrite']) { $file = $directory->copy(G_MODULESPATH . basename($module_dir), true); } else { throw new Exception(_MODULE_BOOTSTRAP_MODULEEXISTS); } } else { $file = $directory->copy(G_MODULESPATH . basename($module_dir)); } $this->setMessageVar(_MODULE_BOOTSTRAP_MODULEINSTALLED, 'success'); } catch (Exception $e) { $smarty->assign("T_EXCEPTION_TRACE", $e->getTraceAsString()); $message = $e->getMessage() . ' (' . $e->getCode() . ') <a href = "javascript:void(0)" onclick = "eF_js_showDivPopup(event, \'' . _ERRORDETAILS . '\', 2, \'error_details\')">' . _MOREINFO . '</a>'; $this->setMessageVar($message, 'failure'); } } $smarty->assign("T_FORM", $form->toArray()); return true; }