Skip to content

Instantly share code, notes, and snippets.

@Bruno17
Last active November 19, 2017 20:53
Show Gist options
  • Save Bruno17/27b873fd397e5beef8c20914747bf270 to your computer and use it in GitHub Desktop.
Save Bruno17/27b873fd397e5beef8c20914747bf270 to your computer and use it in GitHub Desktop.
MODX Revolution - snippet for recreating xPDO - schema from map-files
<?php
class rebuildSchemaFromMap{
public $packageName = '';
public $packagePath = '';
public $modelPath = '';
public $dbtype = '';
public $defaultEngine = 'MyISAM';
public $objects= array();
public function __construct(& $modx,$config = array()) {
$this->modx= & $modx;
$this->packageName = $modx->getOption('packageName',$config,'modx');
if ($this->packageName == 'modx'){
$config['packagePath'] = '';
}
$this->packagePath = $modx->getOption('core_path') . $modx->getOption('packagePath',$config,'components/' . $this->packageName . '/');
$this->modelPath = $this->packagePath . 'model/';
$this->dbtype = $modx->getOption('dbtype',$config,$modx->config['dbtype']);
$this->defaultEngine = $modx->getOption('defaultEngine',$config,'MyISAM');
}
public function getClassnamesFromMetadata(){
$modx = & $this->modx;
$classes = array();
if (is_string($this->packageName) && !empty($this->packageName)) {
$metaFile = $this->modelPath . $this->packageName . '/metadata.' . $this->dbtype . '.php';
if (file_exists($metaFile)) {
$xpdo_meta_map = '';
include $metaFile;
if (!empty($xpdo_meta_map)) {
foreach ($xpdo_meta_map as $extends => $classnames) {
$classes = array_unique(array_merge($classes,$classnames));
}
}
} else {
$modx->log(xPDO::LOG_LEVEL_WARN, "Could not load package metadata for package {$packageName}.");
}
} else {
$modx->log(xPDO::LOG_LEVEL_ERROR, 'setPackageMeta called with an invalid package name.');
}
return $classes;
}
public function parseMapFiles($classnames){
if (is_array($classnames)){
foreach ($classnames as $classname){
$mapFile = $this->modelPath . $this->packageName . '/' . $this->dbtype . '/' .strtolower($classname) . '.map.inc.php';
$xpdo_meta_map = array();
if (file_exists($mapFile)) {
include $mapFile;
if (!empty($xpdo_meta_map)) {
$this->buildObject($xpdo_meta_map);
}
}
}
}
}
public function buildField($fieldname,$fieldMeta){
$spaces = ' ';
$field = '';
if (is_string($fieldname) && !empty($fieldname)){
if (is_array($fieldMeta)){
$field = $spaces . "<field key=\"$fieldname\" ";
foreach ($fieldMeta as $fieldAttribute => $value){
if (is_bool($value)){
$value = $value ? 'true' : 'false';
}
$field .= "$fieldAttribute=\"$value\" ";
}
$field .= "/>";
}
}
return $field;
}
public function buildFields($meta){
$fields = array();
$fieldMetas = $meta['fieldMeta'];
if (is_array($fieldMetas)){
foreach ($fieldMetas as $fieldname => $fieldMeta){
$fields[$fieldname] = $this->buildField($fieldname,$fieldMeta);
}
}
return $fields;
}
public function buildIndexColumn($columnname,$columnAttributes){
$spaces = ' ';
$field = '';
if (is_string($columnname) && !empty($columnname)){
if (is_array($columnAttributes)){
$field = $spaces . "<column key=\"$columnname\" ";
foreach ($columnAttributes as $fieldAttribute => $value){
if (is_bool($value)){
$value = $value ? 'true' : 'false';
}
$field .= "$fieldAttribute=\"$value\" ";
}
$field .= "/>";
}
}
return $field;
}
public function buildIndexColumns($indexMeta){
$columns = $indexMeta['columns'];
if (is_array($columns)){
foreach ($columns as $columnname => $columnAttributes){
$columns[$columnname] = $this->buildIndexColumn($columnname,$columnAttributes);
}
}
return $columns;
}
public function buildIndex($indexname,$indexMeta){
$spaces = ' ';
$field = '';
if (is_string($indexname) && !empty($indexname)){
if (is_array($indexMeta)){
$columns = $this->buildIndexColumns($indexMeta);
$field = $spaces . "<index name=\"$indexname\" ";
foreach ($indexMeta as $fieldAttribute => $value){
if (is_bool($value)){
$value = $value ? 'true' : 'false';
}
if (is_string($value)){
$field .= "$fieldAttribute=\"$value\" ";
}
}
$field .= ">\n";
$field .= implode("\n",$columns) . "\n";
$field .= $spaces . "</index>";
}
}
return $field;
}
public function buildIndexes($meta){
$indexes = array();
$indexMetas = $meta['indexes'];
if (is_array($indexMetas)){
foreach ($indexMetas as $indexname => $indexMeta){
$indexes[$indexname] = $this->buildIndex($indexname,$indexMeta);
}
}
return $indexes;
}
public function buildObject($xpdo_meta_map){
$spaces = ' ';
$keys = array_keys($xpdo_meta_map);
$classname = $keys[0];
$extends = $xpdo_meta_map[$classname]['extends'];
$table = $xpdo_meta_map[$classname]['table'];
$table = !empty($table) ? " table=\"$table\"" : "";
$fields = $this->buildFields($xpdo_meta_map[$classname]);
$indexes = $this->buildIndexes($xpdo_meta_map[$classname]);
$aggregates = $this->buildRelations($xpdo_meta_map[$classname],'aggregate');
$composites = $this->buildRelations($xpdo_meta_map[$classname],'composite');
$object = $spaces . "<object class=\"$classname\"$table extends=\"$extends\">\n";
$object .= implode("\n",$fields) . "\n";
if (!empty($indexes)){
$object .= implode("\n",$indexes) . "\n";
}
if (!empty($aggregates)){
$object .= implode("\n",$aggregates) . "\n";
}
if (!empty($composites)){
$object .= implode("\n",$composites) . "\n";
}
$object .= $spaces . "</object>";
$this->objects[$classname] = $object;
}
public function buildRelationCriteria($fieldMeta){
$spaces = ' ';
$criteria = $fieldMeta['criteria'];
$field = '';
if (is_array($criteria)){
$keys = array_keys($criteria);
$target = $keys[0];
$c = $criteria[$target];
$field = $spaces . "<criteria target=\"$target\"><![CDATA[\n";
$field .= $spaces . ' ' . json_encode($c) . "\n";
$field .= $spaces . "]]></criteria>\n";
}
return $field;
}
public function buildRelation($fieldname,$fieldMeta,$type){
$spaces = ' ';
$field = '';
if (is_string($fieldname) && !empty($fieldname)){
if (is_array($fieldMeta)){
$criteria = $this->buildRelationCriteria($fieldMeta);
$field = $spaces . "<$type alias=\"$fieldname\" ";
foreach ($fieldMeta as $fieldAttribute => $value){
if (is_bool($value)){
$value = $value ? 'true' : 'false';
}
if (is_string($value)){
$field .= "$fieldAttribute=\"$value\" ";
}
}
if (!empty($criteria)){
$field .= ">\n";
$field .= $criteria;
$field .= $spaces . "</$type>";
} else {
$field .= "/>";
}
}
}
return $field;
}
public function buildRelations($meta,$type){
$fields = array();
$fieldMetas = $meta[$type . 's'];
if (is_array($fieldMetas)){
foreach ($fieldMetas as $fieldname => $fieldMeta){
$fields[$fieldname] = $this->buildRelation($fieldname,$fieldMeta,$type);
}
}
return $fields;
}
public function run(){
$classnames = $this->getClassnamesFromMetadata();
$this->parseMapFiles($classnames);
$output = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
$output .= "<model package=\"$this->packageName\" baseClass=\"xPDOObject\" platform=\"$this->dbtype\" defaultEngine=\"$this->defaultEngine\" phpdoc-package=\"$this->packageName\" phpdoc-subpackage=\"\" version=\"1.1\">\n";
$output .= implode("\n",$this->objects) . "\n";
$output .= "</model>";
return $output;
}
}
$app = new rebuildSchemaFromMap($modx,$scriptProperties);
return '<textarea style="width:100%;height:400px;">' . $app->run() . '</textarea>';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment