Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature "Additional Data for Page Editor Plugins" #612

Merged
merged 1 commit into from
Aug 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 102 additions & 1 deletion Services/COPage/classes/class.ilCOPageExporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,32 @@ class ilCOPageExporter extends ilXmlExporter
private $ds;
protected $config;

/**
* List of dependencies for page component plugins with an own exporter
*
* The list of ids in the dependency definition has the following format:
* <parent_type>:<page_id>:<lang>:<pc_id>
*
* The implementation assumes the following call sequence of methods
* to avoid a multiple instatiation of page objects
* 1. init()
* 2. getXmlRepresentation()
* 3. getXmlExportTailDependencies()
*
*
* @var array plugin_name => depencency definition array
*/
protected $plugin_dependencies = array();

/**
* Initialisation
*/
function init()
{
global $DIC;
/** @var ilPluginAdmin $ilPluginAdmin */
$ilPluginAdmin = $DIC['ilPluginAdmin'];

include_once("./Services/COPage/classes/class.ilCOPageDataSet.php");
$this->ds = new ilCOPageDataSet();
$this->ds->setExportDirectories($this->dir_relative, $this->dir_absolute);
Expand All @@ -29,6 +50,23 @@ function init()
{
$this->ds->setMasterLanguageOnly(true);
}

// collect all page component plugins that have their own exporter
require_once('Services/COPage/classes/class.ilPageComponentPluginExporter.php');
foreach(ilPluginAdmin::getActivePluginsForSlot(IL_COMP_SERVICE, "COPage", "pgcp") as $plugin_name)
{
if ($ilPluginAdmin->supportsExport(IL_COMP_SERVICE, "COPage", "pgcp", $plugin_name))
{
require_once('Customizing/global/plugins/Services/COPage/PageComponent/'
.$plugin_name.'/classes/class.il'.$plugin_name.'Exporter.php');

$this->plugin_dependencies[$plugin_name] = array(
"component" => "Plugins/" . $plugin_name,
"entity" => "pgcp",
"ids" => array()
);
}
}
}


Expand Down Expand Up @@ -118,7 +156,13 @@ function getXmlExportTailDependencies($a_entity, $a_target_release, $a_ids)
"ids" => $pg_ids)
);
}


if (!empty($this->plugin_dependencies))
{
// use numeric keys instead plugin names
return array_values($this->plugin_dependencies);
}

return array();
}

Expand Down Expand Up @@ -159,6 +203,7 @@ public function getXmlRepresentation($a_entity, $a_schema_version, $a_id)
$page_object = ilPageObjectFactory::getInstance($id[0], $id[1], 0, $l);
$page_object->buildDom();
$page_object->insertInstIntoIDs(IL_INST_ID);
$this->extractPluginProperties($page_object);
$pxml = $page_object->getXMLFromDom(false, false, false, "", true);
$pxml = str_replace("&","&amp;", $pxml);
$xml.= '<PageObject Language="'.$l.'" Active="'.$page_object->getActive().'" ActivationStart="'.$page_object->getActivationStart().'" ActivationEnd="'.
Expand Down Expand Up @@ -213,6 +258,62 @@ function getValidSchemaVersions($a_entity)
}
}

/**
* Extract the properties of the plugged page contents
* The page XML is scanned for plugged contents with own exporters
* Their ids are added as dependencies
*
* Called from getXmlRepresentation() for each handled page object
* Extracted data is used by dependent exporters afterwards
*
* @param ilPageObject $a_page
*/
protected function extractPluginProperties($a_page)
{
if (empty($this->plugin_dependencies))
{
return;
}

$a_page->buildDom();
$domdoc = $a_page->getDomDoc();
$xpath = new DOMXPath($domdoc);
$nodes = $xpath->query("//PageContent[child::Plugged]");

/** @var DOMElement $pcnode */
foreach($nodes as $pcnode)
{
// page content id (unique in the page)
$pc_id = $pcnode->getAttribute('PCID');
$plnode = $pcnode->childNodes->item(0);
$plugin_name = $plnode->getAttribute('PluginName');
$plugin_version = $plnode->getAttribute('PluginVersion');

// dependency should be exported
if (isset($this->plugin_dependencies[$plugin_name]))
{
// construct a unique dependency id of the plugged page content
$id = $a_page->getParentType()
. ':' . $a_page->getId()
. ':' . $a_page->getLanguage()
. ':' . $pc_id;

$properties = array();
/** @var DOMElement $child */
foreach($plnode->childNodes as $child)
{
$properties[$child->getAttribute('Name')] = $child->nodeValue;
}

// statical provision of content to the exporter classes
ilPageComponentPluginExporter::setPCVersion($id, $plugin_version);
ilPageComponentPluginExporter::setPCProperties($id, $properties);

// each plugin exporter gets only the ids of its own content
$this->plugin_dependencies[$plugin_name]['ids'][] = $id;
}
}
}
}

?>
151 changes: 150 additions & 1 deletion Services/COPage/classes/class.ilCOPageImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,40 @@ class ilCOPageImporter extends ilXmlImporter
*/
protected $ds;

/**
* Names of active plugins with own importers for additional data
* @var array
*/
protected $importer_plugins = array();

/**
* Initialisation
*/
function init()
{
global $DIC;
/** @var ilPluginAdmin $ilPluginAdmin */
$ilPluginAdmin = $DIC['ilPluginAdmin'];

include_once("./Services/COPage/classes/class.ilCOPageDataSet.php");
$this->ds = new ilCOPageDataSet();
$this->ds->setDSPrefix("ds");
$this->config = $this->getImport()->getConfig("Services/COPage");

$this->log = ilLoggerFactory::getLogger('copg');

// collect all page component plugins that have their own exporter
require_once('Services/COPage/classes/class.ilPageComponentPluginImporter.php');
foreach(ilPluginAdmin::getActivePluginsForSlot(IL_COMP_SERVICE, "COPage", "pgcp") as $plugin_name)
{
if ($ilPluginAdmin->supportsExport(IL_COMP_SERVICE, "COPage", "pgcp", $plugin_name))
{
require_once('Customizing/global/plugins/Services/COPage/PageComponent/'
.$plugin_name.'/classes/class.il'.$plugin_name.'Importer.php');

$this->importer_plugins[] = $plugin_name;
}
}
}


Expand Down Expand Up @@ -92,6 +115,7 @@ function importXmlRepresentation($a_entity, $a_id, $a_xml, $a_mapping)
$page->setImportMode(true);
$page->setXMLContent($next_xml);
$page->updateFromXML();
$this->extractPluginProperties($page);
}
else
{
Expand All @@ -113,6 +137,7 @@ function importXmlRepresentation($a_entity, $a_id, $a_xml, $a_mapping)
$new_page->setActivationEnd($page_data["ActivationEnd"]);
$new_page->setShowActivationInfo($page_data["ShowActivationInfo"]);
$new_page->createFromXML();
$this->extractPluginProperties($new_page);
}

$a_xml = substr($a_xml, $p);
Expand Down Expand Up @@ -160,7 +185,8 @@ function finalProcessing($a_mapping)
$il = $new_page->resolveIntLinks();
$this->log->debug("resolve internal link for page ".$id[0]."-".$id[1]."-".$id[2]);
}
if ($med || $fil || $il)
$plug = $this->replacePluginProperties($new_page);
if ($med || $fil || $il || $plug)
{
$new_page->update(false, true);
}
Expand All @@ -170,6 +196,129 @@ function finalProcessing($a_mapping)
//}
$this->log->debug("end");
}

/**
* Extract the properties of the plugged page contents
* The page XML is scanned for plugged contents with own importers
*
* Called from importXmlRepresentation() for each handled page object
* Extracted data is used by plugin importers afterwards
*
* @param ilPageObject $a_page
*/
protected function extractPluginProperties($a_page)
{
if (empty($this->importer_plugins))
{
return;
}

$a_page->buildDom();
$domdoc = $a_page->getDomDoc();
$xpath = new DOMXPath($domdoc);
$nodes = $xpath->query("//PageContent[child::Plugged]");

/** @var DOMElement $pcnode */
foreach($nodes as $pcnode)
{
// page content id (unique in the page)
$pc_id = $pcnode->getAttribute('PCID');
$plnode = $pcnode->childNodes->item(0);
$plugin_name = $plnode->getAttribute('PluginName');
$plugin_version = $plnode->getAttribute('PluginVersion');

// additional data will be imported
if (in_array($plugin_name, $this->importer_plugins))
{
// get the id of the mapped plugged page content
$id = $a_page->getParentType()
. ':' . $a_page->getId()
. ':' . $a_page->getLanguage()
. ':' . $pc_id;

$properties = array();
/** @var DOMElement $child */
foreach($plnode->childNodes as $child)
{
$properties[$child->getAttribute('Name')] = $child->nodeValue;
}

// statical provision of content to the pluged importer classes
ilPageComponentPluginImporter::setPCVersion($id, $plugin_version);
ilPageComponentPluginImporter::setPCProperties($id, $properties);
}
}
}

/**
* Replace the properties of the plugged page contents
* The page XML is scanned for plugged contents with own importers
* The pluged content is replace
*
* Called finalProcessing() for each handled page
* Extracted data is used by dependent plugin importers afterwards
*
* @param ilPageObject $a_page
* @return bool page is modified
*/
public function replacePluginProperties($a_page)
{
if (empty($this->importer_plugins))
{
return false;
}

$a_page->buildDom();
$domdoc = $a_page->getDomDoc();
$xpath = new DOMXPath($domdoc);
$nodes = $xpath->query("//PageContent[child::Plugged]");

$modified = false;

/** @var DOMElement $pcnode */
foreach($nodes as $pcnode)
{
// page content id (unique in the page)
$pc_id = $pcnode->getAttribute('PCID');
$plnode = $pcnode->childNodes->item(0);
$plugin_name = $plnode->getAttribute('PluginName');

// get the id of the mapped plugged page content
$id = $a_page->getParentType()
. ':' . $a_page->getId()
. ':' . $a_page->getLanguage()
. ':' . $pc_id;

$plugin_version = ilPageComponentPluginImporter::getPCVersion($id);
$properties = ilPageComponentPluginImporter::getPCProperties($id);

// update the version if modified by the plugin importer
if (isset($plugin_version))
{
$plnode->setAttribute('PluginVersion', $plugin_version);
$modified = true;
}

// update the properties if modified by the plugin importer
if (is_array($properties))
{
/** @var DOMElement $child */
foreach($plnode->childNodes as $child)
{
$plnode->removeChild($child);
}
foreach ($properties as $name => $value)
{
$child = new DOMElement('PluggedProperty', $value);
$plnode->appendChild($child);
$child->setAttribute('Name',$name);
}
$modified = true;
}
}

return $modified;
}
}

?>
Loading