From: <nat...@us...> - 2010-10-28 20:02:45
|
Author: nathangray Date: Thu Oct 28 22:02:32 2010 New Revision: 32735 URL: http://www.egroupware.org/viewvc/egroupware?rev=32735&view=rev Log: Add ability to import a previously exported sitemgr site. Added: trunk/sitemgr/inc/class.sitemgr_import_xml.inc.php Modified: trunk/sitemgr/inc/class.Sites_UI.inc.php trunk/sitemgr/setup/etemplates.inc.php trunk/sitemgr/templates/default/listsites.tpl Modified: trunk/sitemgr/inc/class.Sites_UI.inc.php URL: http://www.egroupware.org/viewvc/egroupware/trunk/sitemgr/inc/class.Sites_UI.inc.php?rev=32735&r1=32734&r2=32735&view=diff ============================================================================== --- trunk/sitemgr/inc/class.Sites_UI.inc.php (original) +++ trunk/sitemgr/inc/class.Sites_UI.inc.php Thu Oct 28 22:02:32 2010 @@ -20,6 +20,7 @@ 'edit' => True, 'delete' => True, 'export' => True, + 'import' => True, ); var $start = 0; @@ -82,7 +83,9 @@ $GLOBALS['egw']->template->set_block('site_list_t','site_list','list'); $GLOBALS['egw']->template->set_var('add_action',$GLOBALS['egw']->link('/index.php','menuaction=sitemgr.Sites_UI.edit')); + $GLOBALS['egw']->template->set_var('import_action',$GLOBALS['egw']->link('/index.php','menuaction=sitemgr.Sites_UI.import')); $GLOBALS['egw']->template->set_var('lang_add',lang('Add')); + $GLOBALS['egw']->template->set_var('lang_import',lang('Import')); $GLOBALS['egw']->template->set_var('title_sites',lang('Sitemgr Websites')); $GLOBALS['egw']->template->set_var('lang_search',lang('Search')); $GLOBALS['egw']->template->set_var('actionurl',$GLOBALS['egw']->link('/index.php','menuaction=sitemgr.Sites_UI.list_sites')); @@ -366,6 +369,19 @@ } } + public function import() + { + if (!$GLOBALS['egw']->acl->check('run',1,'admin')) + { + $GLOBALS['egw']->common->egw_header(); + echo parse_navbar(); + $this->deny(); + } + $GLOBALS['egw']->redirect_link('/index.php', array( + 'menuaction' => 'sitemgr.sitemgr_import_xml.ui_import', + )); + } + function deny() { echo '<p><center><b>'.lang('Access not permitted').'</b></center>'; Added: trunk/sitemgr/inc/class.sitemgr_import_xml.inc.php URL: http://www.egroupware.org/viewvc/egroupware/trunk/sitemgr/inc/class.sitemgr_import_xml.inc.php?rev=32735&view=auto ============================================================================== --- trunk/sitemgr/inc/class.sitemgr_import_xml.inc.php (added) +++ trunk/sitemgr/inc/class.sitemgr_import_xml.inc.php Thu Oct 28 22:02:32 2010 @@ -1,0 +1,498 @@ +<?php +/** + * eGroupWare + * + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @package sitemgr + * @subpackage importexport + * @link http://www.egroupware.org + * @author Nathan Gray + * @copyright Nathan Gray + * @version $Id$ + */ + +/** + * class import_xml + * + * Import a site. + */ +class sitemgr_import_xml implements importexport_iface_import_plugin { + + /** + * List of errors encountered + */ + protected $errors = array(); + + /** + * Import results + */ + protected $results = array(); + + protected $common = null; + + /** + * Key queues to keep track of where we are + */ + protected $cat_id = array(); + protected $block_id = array(); + protected $page_id = array(); + + private static $debug = 1; + + // Due to limitations in creating Sites_UI, make the import directly accessable + public $public_functions = array( + 'ui_import' => true + ); + + public function __construct() { + $this->common = $GLOBALS['Common_BO'] = CreateObject('sitemgr.Common_BO'); + } + + /** + * Provide a base UI (not part of importexport) + * so sites can be imported directly as part of sitemgr + * + * The usual eTemplate stuff is not available because of specific exceptions in eTemplate, + * so we use the normal $_FILES array. + */ + public function ui_import() { + if (!$GLOBALS['egw']->acl->check('run',1,'admin')) { + $GLOBALS['egw']->common->egw_header(); + echo parse_navbar(); + return; + } + $data = array(); + if($_FILES['exec']) { + $this->reader = new XMLReader(); + $this->reader->open($_FILES['exec']['tmp_name']['file']); + $this->import_record(); + $data['message'] = lang('Imported') . "\n".implode("\n", $this->errors); + $GLOBALS['egw']->redirect_link('/index.php', array( + 'menuaction' => 'sitemgr.Sites_UI.edit', + 'site_id' => CURRENT_SITE_ID + )); + } + $GLOBALS['egw']->common->egw_header(); + echo parse_navbar(); + $template = new etemplate('sitemgr.import_ui'); + echo $template->exec('sitemgr.sitemgr_import_xml.ui_import', $data, array(), array()); + } + + /** + * imports a site from the given stream + * + * @param stream $_stream + * @param definition $_definition + * @return int number of successful imports + */ + public function import( $_stream, importexport_definition $_definition ) { + } + + /** + * returns translated name of plugin + * + * @return string name + */ + public static function get_name() { + return lang('Import site'); + } + + /** + * returns translated (user) description of plugin + * + * @return string descriprion + */ + public static function get_description() { + return lang('Import a SiteMgr website'); + } + + /** + * retruns file suffix(s) plugin can handle (e.g. csv) + * + * @return string suffix (comma seperated) + */ + public static function get_filesuffix() { + return 'xml'; + } + + /** + * return etemplate components for options. + * @abstract We can't deal with etemplate objects here, as an uietemplate + * objects itself are scipt orientated and not "dialog objects" + * + * @return array ( + * name => string, + * content => array, + * sel_options => array, + * preserv => array, + * ) + */ + public function get_options_etpl() { + return array(); + } + + /** + * returns etemplate name for slectors of this plugin + * + * @return string etemplate name + */ + public function get_selectors_etpl() { + return array(); + } + + /** + * Returns errors that were encountered during importing + * Maximum of one error message per record, but you can concatenate them if you need to + * + * @return Array ( + * record_# => error message + * ) + */ + public function get_errors() { + return $this->errors; + } + + /** + * Returns a list of actions taken, and the number of records for that action. + * Actions are things like 'insert', 'update', 'delete', and may be different for each plugin. + * + * @return Array ( + * action => record count + * ) + */ + public function get_results() { + return $this->results; + } + + /** + * Read the XML stream and import the site(s) + */ + public function import_record() { + while ($this->reader->read()) { + if($this->reader->nodeType == XMLReader::ELEMENT) { + switch($this->reader->name) { + case 'site': + $this->import_site(); + break; + case 'category': + $this->import_category(); + break; + default: + echo $this->reader->name . '<br />'; + } + } + } + } + + protected function import_site() { + if(self::$debug >= 1) { + echo 'Import site ---<br />' ; + } + $site = array(); + $lang_array = array(); + $current_tag = null; + $dest = null; + $this->read_node(array('content_areas', 'categories', 'blocks', 'pages'), $site, $lang_array); + reset($lang_array); + + $site['site_name'] = $site['name']; + $site['dir'] = $site['directory']; + $site['anonuser'] = $site['anonymous_user']; + $site['anonpasswd'] = $site['anonymous_password']; + $site['site_languages'] = implode(',', array_keys($lang_array)); + $this->lang = key($lang_array); + $site['home_page_id'] = 0; + + // Done with the site header for now, save it + $this->site_id = $this->common->sites->add($site); + $site['site_id'] = $this->site_id; + $this->common->sites->so->update_logo_css_params($this->site_id, $site); + $this->common->sites->saveprefs($site, $this->site_id); + $this->common->sites->set_currentsite($this->site_id, 'Administration'); + $this->common->cats->setcurrentcats(); + $this->cat_id[] = $this->site_id; + + // allow all modules for the whole page + $this->common->modules->savemodulepermissions('__PAGE__',$this->site_id,array_keys($this->common->modules->getallmodules())); + + // Set current user as an admin and refresh so the rest of the import works + $this->common->acl->set_adminlist($this->site_id, array($GLOBALS['egw_info']['user']['account_id'])); + $this->common->acl->acl->read_repository(); + + // Skip content areas for now + if($this->reader->name == 'content_areas' && $this->reader->nodeType == XMLReader::ELEMENT) { + while($this->reader->read()) { + if($this->reader->name == 'content_areas' && $this->reader->nodeType == XMLReader::END_ELEMENT) break; + } + $this->reader->read(); // On to next element + } + // Site is a special category + //$this->import_category(); + $this->import_children('site'); + + // Set home page + + } + + protected function import_category() { + $category = array(); + $lang_array = array(); + $current_tag = null; + $dest = null; + + $this->read_node(array('categories', 'blocks', 'pages'), $category, $lang_array); + + if(self::$debug >= 1) { + $name = $category['name'] ? $category['name'] : $lang_array[$this->lang]['name']; + echo 'Import category --- ' . $name . '<br />'; + } + // Save category + if(count($category) > 0) { + $parent_id = count($this->cat_id) > 0 ? end($this->cat_id) : False; + $name = $category['name'] ? $category['name'] : $lang_array[$this->lang]['name']; + $description = $category['description'] ? $category['description'] : $lang_array[$this->lang]['description']; + $result = $this->common->cats->addCategory($name, $description, $parent_id); + if($result) { + $this->cat_id[] = $result; + } else { + die('Bad cat'); + } + + // Set current user as an admin, so the rest of the import works + $this->common->acl->grant_permissions($GLOBALS['egw_info']['user']['account_id'], end($this->cat_id), true, true); + $this->common->acl->acl->read_repository(); + + foreach($lang_array as $lang => $data) { + $this->common->cats->saveCategoryInfo( + end($this->cat_id), + $data['name'], + $data['description'], + $lang, + $category['sort_order'], + $category['state'], + $parent_id + ); + } + } + $this->common->cats->setcurrentcats(); + + if(!($this->reader->name == 'category' && $this->reader->nodeType == XMLReader::END_ELEMENT)) { + $this->import_children('category'); + } + array_pop($this->cat_id); + } + + /** + * Many of the elements can have the same children, so abstract the search and handling + */ + protected function import_children($tag) { + if(!$tag) { + $tag = $this->reader->name; + } + if(self::$debug >= 1) { + echo 'Import children of ' . $tag . ' ---<br />'; + } + + // Children + while($this->reader->read()) { + if($this->reader->name == $tag && $this->reader->nodeType == XMLReader::END_ELEMENT) { + break; + } + if($this->reader->nodeType == XMLReader::ELEMENT) { + switch($this->reader->name) { + case 'category': + $this->import_category(); + break; + case 'block': + $this->import_block(); + break; + case 'page': + $this->import_page(); + break; + default: + // categories, blocks, pages + + break; + } + } else if($this->reader->nodeType == XMLReader::END_ELEMENT) { + //echo 'Done with ' . $this->reader->name . '<br />'; + // Blocks are the last one, so just end + //if($this->reader->name == 'blocks') break; + } else { + break; + } + } + + if(self::$debug >= 1) { + echo 'Done with children of ' . $tag . ' ---<br />'; + } + } + + protected function import_block() { + if(self::$debug >= 1) { + echo 'Import block ---<br />'; + } + $block = array(); + $lang_array = array(); + $current_tag = null; + $dest = null; + + $this->read_node(array('contents'), $block, $lang_array); + + // Save block + if(count($block) > 0) { + $block_obj = CreateObject('sitemgr.Block_SO', $block); + $block_obj->cat_id = end($this->cat_id); + $block_obj->page_id = count($this->page_id > 0) ? end($this->page_id) : 0; + $block_obj->module_name = $block['module']; + $block_obj->module_id = $this->common->modules->getmoduleid($block['module']); + $block_obj->state = 0; + if($block['arguments']) { + $block_obj->arguments = unserialize($block['arguments']); + } + + $result = $this->common->content->addblock($block_obj); + if($result) { + $this->block_id[] = $result; + $block_obj->id = $result; + $this->common->content->createversion(end($this->block_id)); + $versions = $this->common->content->getallversionsforblock($block_obj->id,$lang); + $block_obj->version = end(array_keys($versions)); + $this->common->content->savepublicdata($block_obj); + } else { + $this->errors[] = lang('Could not add block %1', $block['title']); + return; + } + foreach($lang_array as $lang => $data) { + foreach($data as $key => $value) { + if(property_exists($block_obj, $key)) $block_obj->$key = $value; + } + $this->common->content->saveblockdata($block_obj, array(), array(), $lang); + $result = $this->common->content->saveblockdatalang($block_obj, array(), $lang); + } + } + + // Content areas + while($this->reader->read()) { + if(in_array($this->reader->name, array('block', 'contents')) && $this->reader->nodeType == XMLReader::END_ELEMENT) break; + if($this->reader->name == 'content') { + $this->import_content($this->reader->getAttribute('lang')); + } + } + + array_pop($this->block_id); + } + + protected function import_content($lang) { + if(self::$debug >= 1) { + echo 'Import content ---<br />'; + } + $content = array(); + $lang_array = array(); + $current_tag = null; + $dest = null; + + $this->read_node(array(), $content, $lang_array); + if(count($content) > 0) { + $versions = $this->common->content->getallversionsforblock(end($this->block_id), $lang); + $version_id = key($versions); + $block_obj = $this->common->content->getblock(end($this->block_id), $lang); + foreach($content as $key => &$value) { + if($value == serialize(false)) { + $value = false; + continue; + } else { + $unserialized = unserialize(trim($value)); + if($unserialized !== false) { + $value = $unserialized; + } + } + } + $versions[$version_id] = $content['arguments'];//array_merge($versions[$version_id], $content); + unset($versions[$version_id]['id']); + unset($versions[$version_id]['state']); + $state = array($version_id => $content['state']); + if($versions[$version_id]) { + $result = $this->common->content->saveversiondatalang($block_obj->id, $version_id, $versions[$version_id], $lang); + } + $this->common->content->so->saveversionstate($block_obj->id, $version_id, $content['state']); + } + } + + protected function import_page() { + if(self::$debug >= 1) { + echo 'Import page ---<br />'; + } + $page = array(); + $lang_array = array(); + $current_tag = null; + $dest = null; + $this->read_node(array('page', 'blocks', 'categories'), $page, $lang_array); + if(count($page) > 0) { + $result = $this->common->pages->addPage(end($this->cat_id)); + if(!$result) { + $this->errors[] = "Unable to add page '{$page['name']}'"; + return; + } else { + $this->page_id[] = $result; + } + $page_obj = $this->common->pages->getPage($result); + foreach($page as $key => $value) { + if(property_exists($page_obj, $key)) { + $page_obj->$key = $value; + } + } + foreach($lang_array as $lang => $data) { + foreach($data as $key => &$value) { + if($value == serialize(false)) { + $value = false; + continue; + } else { + $unserialized = unserialize($value); + if($unserialized !== false) { + $value = $unserialized; + } + } + if(property_exists($page_obj, $key)) { + $page_obj->$key = $value; + } + } + $this->common->pages->savePageInfo($page_obj, $lang); + } + } + if(!($this->reader->name == 'page' && $this->reader->nodeType == XMLReader::END_ELEMENT)) { + $this->import_children('page'); + } + array_pop($this->page_id); + } + + protected function read_node($stop_tags, &$data, &$lang_array) { + if(self::$debug >= 1) { + echo 'Read node (' . $this->reader->name . ') ---<br />' ; + } + $start_tag = $this->reader->name; + $current_tag = null; + $dest = null; + + while($this->reader->read()) { + if(in_array($this->reader->name, $stop_tags) || + $this->reader->name == $start_tag && $this->reader->nodeType == XMLReader::END_ELEMENT) { + break; + } + if($this->reader->nodeType == XMLReader::ELEMENT) { + $current_tag = $this->reader->name; + $dest =& $data[$current_tag]; + } else if($this->reader->nodeType == XMLReader::END_ELEMENT) { + $current_tag = null; + continue; + } + if($current_tag != null) { + if($this->reader->getAttribute('lang')) { + $dest =& $lang_array[$this->reader->getAttribute('lang')][$current_tag]; + } + $dest .= $this->reader->value; + } + } + } +} +?> Modified: trunk/sitemgr/setup/etemplates.inc.php URL: http://www.egroupware.org/viewvc/egroupware/trunk/sitemgr/setup/etemplates.inc.php?rev=32735&r1=32734&r2=32735&view=diff ============================================================================== --- trunk/sitemgr/setup/etemplates.inc.php (original) +++ trunk/sitemgr/setup/etemplates.inc.php Thu Oct 28 22:02:32 2010 @@ -2,7 +2,7 @@ /** * eGroupWare - eTemplates for Application sitemgr * http://www.egroupware.org - * generated by soetemplate::dump4setup() 2010-10-25 17:14 + * generated by soetemplate::dump4setup() 2010-10-28 14:01 * * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @package sitemgr @@ -13,6 +13,8 @@ $templ_version=1; $templ_data[] = array('name' => 'sitemgr.export.selection','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:2:{s:4:"type";s:6:"select";s:4:"name";s:7:"site_id";}}}s:4:"rows";i:1;s:4:"cols";i:1;s:4:"name";s:9:"selection";s:7:"options";a:0:{}}}','size' => '','style' => '','modified' => '1288047117',); + +$templ_data[] = array('name' => 'sitemgr.import_ui','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:1:{s:2:"h1";s:10:",!@message";}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:11:"all,message";s:4:"name";s:7:"message";}}i:2;a:1:{s:1:"A";a:2:{s:4:"type";s:4:"file";s:4:"name";s:4:"file";}}i:3;a:1:{s:1:"A";a:2:{s:4:"type";s:6:"button";s:5:"label";s:6:"Import";}}}s:4:"rows";i:3;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1288137215',); $templ_data[] = array('name' => 'sitemgr.notifications','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:8:{i:0;a:2:{s:1:"A";s:3:"340";s:1:"B";s:3:"340";}i:1;a:2:{s:1:"A";a:5:{s:4:"type";s:5:"label";s:4:"span";s:1:"2";s:7:"no_lang";s:1:"1";s:5:"align";s:6:"center";s:4:"name";s:3:"msg";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"hrule";s:4:"span";s:1:"2";s:5:"align";s:6:"center";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:3;a:2:{s:1:"A";a:4:{s:4:"type";s:8:"template";s:4:"span";s:1:"2";s:5:"align";s:6:"center";s:4:"name";s:27:"sitemgr.notifications.title";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:4;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"hrule";s:4:"span";s:1:"2";s:5:"align";s:6:"center";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:5;a:2:{s:1:"A";a:5:{s:4:"type";s:8:"template";s:4:"size";s:5:"entry";s:4:"span";s:1:"2";s:5:"align";s:6:"center";s:4:"name";s:26:"sitemgr.notifications.list" ;}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:6;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"hrule";s:4:"span";s:1:"2";s:5:"align";s:6:"center";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:7;a:2:{s:1:"A";a:4:{s:4:"type";s:6:"button";s:5:"label";s:3:"Add";s:5:"align";s:5:"right";s:4:"name";s:3:"add";}s:1:"B";a:3:{s:4:"type";s:6:"button";s:5:"label";s:15:"Manage messages";s:4:"name";s:8:"messages";}}}s:4:"rows";i:7;s:4:"cols";i:2;}}','size' => '','style' => '','modified' => '1093302004',); Modified: trunk/sitemgr/templates/default/listsites.tpl URL: http://www.egroupware.org/viewvc/egroupware/trunk/sitemgr/templates/default/listsites.tpl?rev=32735&r1=32734&r2=32735&view=diff ============================================================================== --- trunk/sitemgr/templates/default/listsites.tpl (original) +++ trunk/sitemgr/templates/default/listsites.tpl Thu Oct 28 22:02:32 2010 @@ -47,6 +47,11 @@ <td><form method="POST" action="{doneurl}"> <input type="submit" name="done" value="{lang_done}"> </form></td> + <td /> + <td /> + <td align="right"><form method="POST" action="{import_action}"> + <input type="submit" name="import" value="{lang_import}"> + </form></td> </tr> <!-- END add --> |